]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/gdsys/405ep/iocon.c
Merge branch 'u-boot-imx/master' into 'u-boot-arm/master'
[karo-tx-uboot.git] / board / gdsys / 405ep / iocon.c
1 /*
2  * (C) Copyright 2010
3  * Dirk Eibach,  Guntermann & Drunck GmbH, eibach@gdsys.de
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <common.h>
9 #include <command.h>
10 #include <errno.h>
11 #include <asm/processor.h>
12 #include <asm/io.h>
13 #include <asm/ppc4xx-gpio.h>
14
15 #include "405ep.h"
16 #include <gdsys_fpga.h>
17
18 #include "../common/osd.h"
19 #include "../common/mclink.h"
20
21 #include <i2c.h>
22 #include <pca953x.h>
23 #include <pca9698.h>
24
25 #include <miiphy.h>
26
27 DECLARE_GLOBAL_DATA_PTR;
28
29 #define LATCH0_BASE (CONFIG_SYS_LATCH_BASE)
30 #define LATCH1_BASE (CONFIG_SYS_LATCH_BASE + 0x100)
31 #define LATCH2_BASE (CONFIG_SYS_LATCH_BASE + 0x200)
32
33 #define MAX_MUX_CHANNELS 2
34
35 enum {
36         UNITTYPE_MAIN_SERVER = 0,
37         UNITTYPE_MAIN_USER = 1,
38         UNITTYPE_VIDEO_SERVER = 2,
39         UNITTYPE_VIDEO_USER = 3,
40 };
41
42 enum {
43         HWVER_100 = 0,
44         HWVER_104 = 1,
45         HWVER_110 = 2,
46         HWVER_120 = 3,
47         HWVER_200 = 4,
48         HWVER_210 = 5,
49         HWVER_220 = 6,
50         HWVER_230 = 7,
51 };
52
53 enum {
54         FPGA_HWVER_200 = 0,
55         FPGA_HWVER_210 = 1,
56 };
57
58 enum {
59         COMPRESSION_NONE = 0,
60         COMPRESSION_TYPE1_DELTA = 1,
61         COMPRESSION_TYPE1_TYPE2_DELTA = 3,
62 };
63
64 enum {
65         AUDIO_NONE = 0,
66         AUDIO_TX = 1,
67         AUDIO_RX = 2,
68         AUDIO_RXTX = 3,
69 };
70
71 enum {
72         SYSCLK_147456 = 0,
73 };
74
75 enum {
76         RAM_DDR2_32 = 0,
77         RAM_DDR3_32 = 1,
78 };
79
80 enum {
81         CARRIER_SPEED_1G = 0,
82         CARRIER_SPEED_2_5G = 1,
83 };
84
85 enum {
86         MCFPGA_DONE = 1 << 0,
87         MCFPGA_INIT_N = 1 << 1,
88         MCFPGA_PROGRAM_N = 1 << 2,
89         MCFPGA_UPDATE_ENABLE_N = 1 << 3,
90         MCFPGA_RESET_N = 1 << 4,
91 };
92
93 enum {
94         GPIO_MDC = 1 << 14,
95         GPIO_MDIO = 1 << 15,
96 };
97
98 unsigned int mclink_fpgacount;
99 struct ihs_fpga *fpga_ptr[] = CONFIG_SYS_FPGA_PTR;
100
101 static int setup_88e1518(const char *bus, unsigned char addr);
102
103 int fpga_set_reg(u32 fpga, u16 *reg, off_t regoff, u16 data)
104 {
105         int res;
106
107         switch (fpga) {
108         case 0:
109                 out_le16(reg, data);
110                 break;
111         default:
112                 res = mclink_send(fpga - 1, regoff, data);
113                 if (res < 0) {
114                         printf("mclink_send reg %02lx data %04x returned %d\n",
115                                regoff, data, res);
116                         return res;
117                 }
118                 break;
119         }
120
121         return 0;
122 }
123
124 int fpga_get_reg(u32 fpga, u16 *reg, off_t regoff, u16 *data)
125 {
126         int res;
127
128         switch (fpga) {
129         case 0:
130                 *data = in_le16(reg);
131                 break;
132         default:
133                 if (fpga > mclink_fpgacount)
134                         return -EINVAL;
135                 res = mclink_receive(fpga - 1, regoff, data);
136                 if (res < 0) {
137                         printf("mclink_receive reg %02lx returned %d\n",
138                                regoff, res);
139                         return res;
140                 }
141         }
142
143         return 0;
144 }
145
146 /*
147  * Check Board Identity:
148  */
149 int checkboard(void)
150 {
151         char *s = getenv("serial#");
152
153         puts("Board: ");
154
155         puts("IoCon");
156
157         if (s != NULL) {
158                 puts(", serial# ");
159                 puts(s);
160         }
161
162         puts("\n");
163
164         return 0;
165 }
166
167 static void print_fpga_info(unsigned int fpga, bool rgmii2_present)
168 {
169         u16 versions;
170         u16 fpga_version;
171         u16 fpga_features;
172         unsigned unit_type;
173         unsigned hardware_version;
174         unsigned feature_compression;
175         unsigned feature_osd;
176         unsigned feature_audio;
177         unsigned feature_sysclock;
178         unsigned feature_ramconfig;
179         unsigned feature_carrier_speed;
180         unsigned feature_carriers;
181         unsigned feature_video_channels;
182
183         int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
184
185         FPGA_GET_REG(0, versions, &versions);
186         FPGA_GET_REG(0, fpga_version, &fpga_version);
187         FPGA_GET_REG(0, fpga_features, &fpga_features);
188
189         unit_type = (versions & 0xf000) >> 12;
190         feature_compression = (fpga_features & 0xe000) >> 13;
191         feature_osd = fpga_features & (1<<11);
192         feature_audio = (fpga_features & 0x0600) >> 9;
193         feature_sysclock = (fpga_features & 0x0180) >> 7;
194         feature_ramconfig = (fpga_features & 0x0060) >> 5;
195         feature_carrier_speed = fpga_features & (1<<4);
196         feature_carriers = (fpga_features & 0x000c) >> 2;
197         feature_video_channels = fpga_features & 0x0003;
198
199         if (legacy)
200                 printf("legacy ");
201
202         switch (unit_type) {
203         case UNITTYPE_MAIN_USER:
204                 printf("Mainchannel");
205                 break;
206
207         case UNITTYPE_VIDEO_USER:
208                 printf("Videochannel");
209                 break;
210
211         default:
212                 printf("UnitType %d(not supported)", unit_type);
213                 break;
214         }
215
216         if (unit_type == UNITTYPE_MAIN_USER) {
217                 if (legacy)
218                         hardware_version =
219                                 (in_le16((void *)LATCH2_BASE)>>8) & 0x0f;
220                 else
221                         hardware_version =
222                                   (!!pca9698_get_value(0x20, 24) << 0)
223                                 | (!!pca9698_get_value(0x20, 25) << 1)
224                                 | (!!pca9698_get_value(0x20, 26) << 2)
225                                 | (!!pca9698_get_value(0x20, 27) << 3);
226                 switch (hardware_version) {
227                 case HWVER_100:
228                         printf(" HW-Ver 1.00,");
229                         break;
230
231                 case HWVER_104:
232                         printf(" HW-Ver 1.04,");
233                         break;
234
235                 case HWVER_110:
236                         printf(" HW-Ver 1.10,");
237                         break;
238
239                 case HWVER_120:
240                         printf(" HW-Ver 1.20-1.21,");
241                         break;
242
243                 case HWVER_200:
244                         printf(" HW-Ver 2.00,");
245                         break;
246
247                 case HWVER_210:
248                         printf(" HW-Ver 2.10,");
249                         break;
250
251                 case HWVER_220:
252                         printf(" HW-Ver 2.20,");
253                         break;
254
255                 case HWVER_230:
256                         printf(" HW-Ver 2.30,");
257                         break;
258
259                 default:
260                         printf(" HW-Ver %d(not supported),",
261                                hardware_version);
262                         break;
263                 }
264                 if (rgmii2_present)
265                         printf(" RGMII2,");
266         }
267
268         if (unit_type == UNITTYPE_VIDEO_USER) {
269                 hardware_version = versions & 0x000f;
270                 switch (hardware_version) {
271                 case FPGA_HWVER_200:
272                         printf(" HW-Ver 2.00,");
273                         break;
274
275                 case FPGA_HWVER_210:
276                         printf(" HW-Ver 2.10,");
277                         break;
278
279                 default:
280                         printf(" HW-Ver %d(not supported),",
281                                hardware_version);
282                         break;
283                 }
284         }
285
286         printf(" FPGA V %d.%02d\n       features:",
287                fpga_version / 100, fpga_version % 100);
288
289
290         switch (feature_compression) {
291         case COMPRESSION_NONE:
292                 printf(" no compression");
293                 break;
294
295         case COMPRESSION_TYPE1_DELTA:
296                 printf(" type1-deltacompression");
297                 break;
298
299         case COMPRESSION_TYPE1_TYPE2_DELTA:
300                 printf(" type1-deltacompression, type2-inlinecompression");
301                 break;
302
303         default:
304                 printf(" compression %d(not supported)", feature_compression);
305                 break;
306         }
307
308         printf(", %sosd", feature_osd ? "" : "no ");
309
310         switch (feature_audio) {
311         case AUDIO_NONE:
312                 printf(", no audio");
313                 break;
314
315         case AUDIO_TX:
316                 printf(", audio tx");
317                 break;
318
319         case AUDIO_RX:
320                 printf(", audio rx");
321                 break;
322
323         case AUDIO_RXTX:
324                 printf(", audio rx+tx");
325                 break;
326
327         default:
328                 printf(", audio %d(not supported)", feature_audio);
329                 break;
330         }
331
332         puts(",\n       ");
333
334         switch (feature_sysclock) {
335         case SYSCLK_147456:
336                 printf("clock 147.456 MHz");
337                 break;
338
339         default:
340                 printf("clock %d(not supported)", feature_sysclock);
341                 break;
342         }
343
344         switch (feature_ramconfig) {
345         case RAM_DDR2_32:
346                 printf(", RAM 32 bit DDR2");
347                 break;
348
349         case RAM_DDR3_32:
350                 printf(", RAM 32 bit DDR3");
351                 break;
352
353         default:
354                 printf(", RAM %d(not supported)", feature_ramconfig);
355                 break;
356         }
357
358         printf(", %d carrier(s) %s", feature_carriers,
359                feature_carrier_speed ? "2.5Gbit/s" : "1Gbit/s");
360
361         printf(", %d video channel(s)\n", feature_video_channels);
362 }
363
364 int last_stage_init(void)
365 {
366         int slaves;
367         unsigned int k;
368         unsigned int mux_ch;
369         unsigned char mclink_controllers[] = { 0x24, 0x25, 0x26 };
370         int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
371         u16 fpga_features;
372         int feature_carrier_speed = fpga_features & (1<<4);
373         bool ch0_rgmii2_present = false;
374
375         FPGA_GET_REG(0, fpga_features, &fpga_features);
376
377         if (!legacy)
378                 ch0_rgmii2_present = !pca9698_get_value(0x20, 30);
379
380         print_fpga_info(0, ch0_rgmii2_present);
381         osd_probe(0);
382
383         /* wait for FPGA done */
384         for (k = 0; k < ARRAY_SIZE(mclink_controllers); ++k) {
385                 unsigned int ctr = 0;
386
387                 if (i2c_probe(mclink_controllers[k]))
388                         continue;
389
390                 while (!(pca953x_get_val(mclink_controllers[k])
391                        & MCFPGA_DONE)) {
392                         udelay(100000);
393                         if (ctr++ > 5) {
394                                 printf("no done for mclink_controller %d\n", k);
395                                 break;
396                         }
397                 }
398         }
399
400         if (!legacy && (feature_carrier_speed == CARRIER_SPEED_1G)) {
401                 miiphy_register(bb_miiphy_buses[0].name, bb_miiphy_read,
402                                 bb_miiphy_write);
403                 for (mux_ch = 0; mux_ch < MAX_MUX_CHANNELS; ++mux_ch) {
404                         if ((mux_ch == 1) && !ch0_rgmii2_present)
405                                 continue;
406
407                         setup_88e1518(bb_miiphy_buses[0].name, mux_ch);
408                 }
409         }
410
411         /* wait for slave-PLLs to be up and running */
412         udelay(500000);
413
414         mclink_fpgacount = CONFIG_SYS_MCLINK_MAX;
415         slaves = mclink_probe();
416         mclink_fpgacount = 0;
417
418         if (slaves <= 0)
419                 return 0;
420
421         mclink_fpgacount = slaves;
422
423         for (k = 1; k <= slaves; ++k) {
424                 FPGA_GET_REG(k, fpga_features, &fpga_features);
425                 feature_carrier_speed = fpga_features & (1<<4);
426
427                 print_fpga_info(k, false);
428                 osd_probe(k);
429                 if (feature_carrier_speed == CARRIER_SPEED_1G) {
430                         miiphy_register(bb_miiphy_buses[k].name,
431                                         bb_miiphy_read, bb_miiphy_write);
432                         setup_88e1518(bb_miiphy_buses[k].name, 0);
433                 }
434         }
435
436         return 0;
437 }
438
439 /*
440  * provide access to fpga gpios (for I2C bitbang)
441  * (these may look all too simple but make iocon.h much more readable)
442  */
443 void fpga_gpio_set(unsigned int bus, int pin)
444 {
445         FPGA_SET_REG(bus, gpio.set, pin);
446 }
447
448 void fpga_gpio_clear(unsigned int bus, int pin)
449 {
450         FPGA_SET_REG(bus, gpio.clear, pin);
451 }
452
453 int fpga_gpio_get(unsigned int bus, int pin)
454 {
455         u16 val;
456
457         FPGA_GET_REG(bus, gpio.read, &val);
458
459         return val & pin;
460 }
461
462 void gd405ep_init(void)
463 {
464         unsigned int k;
465
466         if (i2c_probe(0x20)) { /* i2c_probe returns 0 on success */
467                 for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k)
468                         gd->arch.fpga_state[k] |= FPGA_STATE_PLATFORM;
469         } else {
470                 pca9698_direction_output(0x20, 4, 1);
471         }
472 }
473
474 void gd405ep_set_fpga_reset(unsigned state)
475 {
476         int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
477
478         if (legacy) {
479                 if (state) {
480                         out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_RESET);
481                         out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_RESET);
482                 } else {
483                         out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_BOOT);
484                         out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_BOOT);
485                 }
486         } else {
487                 pca9698_set_value(0x20, 4, state ? 0 : 1);
488         }
489 }
490
491 void gd405ep_setup_hw(void)
492 {
493         /*
494          * set "startup-finished"-gpios
495          */
496         gpio_write_bit(21, 0);
497         gpio_write_bit(22, 1);
498 }
499
500 int gd405ep_get_fpga_done(unsigned fpga)
501 {
502         int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
503
504         if (legacy)
505                 return in_le16((void *)LATCH2_BASE)
506                        & CONFIG_SYS_FPGA_DONE(fpga);
507         else
508                 return pca9698_get_value(0x20, 20);
509 }
510
511 /*
512  * FPGA MII bitbang implementation
513  */
514
515 struct fpga_mii {
516         unsigned fpga;
517         int mdio;
518 } fpga_mii[] = {
519         { 0, 1},
520         { 1, 1},
521         { 2, 1},
522         { 3, 1},
523 };
524
525 static int mii_dummy_init(struct bb_miiphy_bus *bus)
526 {
527         return 0;
528 }
529
530 static int mii_mdio_active(struct bb_miiphy_bus *bus)
531 {
532         struct fpga_mii *fpga_mii = bus->priv;
533
534         if (fpga_mii->mdio)
535                 FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
536         else
537                 FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO);
538
539         return 0;
540 }
541
542 static int mii_mdio_tristate(struct bb_miiphy_bus *bus)
543 {
544         struct fpga_mii *fpga_mii = bus->priv;
545
546         FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
547
548         return 0;
549 }
550
551 static int mii_set_mdio(struct bb_miiphy_bus *bus, int v)
552 {
553         struct fpga_mii *fpga_mii = bus->priv;
554
555         if (v)
556                 FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
557         else
558                 FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO);
559
560         fpga_mii->mdio = v;
561
562         return 0;
563 }
564
565 static int mii_get_mdio(struct bb_miiphy_bus *bus, int *v)
566 {
567         u16 gpio;
568         struct fpga_mii *fpga_mii = bus->priv;
569
570         FPGA_GET_REG(fpga_mii->fpga, gpio.read, &gpio);
571
572         *v = ((gpio & GPIO_MDIO) != 0);
573
574         return 0;
575 }
576
577 static int mii_set_mdc(struct bb_miiphy_bus *bus, int v)
578 {
579         struct fpga_mii *fpga_mii = bus->priv;
580
581         if (v)
582                 FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDC);
583         else
584                 FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDC);
585
586         return 0;
587 }
588
589 static int mii_delay(struct bb_miiphy_bus *bus)
590 {
591         udelay(1);
592
593         return 0;
594 }
595
596 struct bb_miiphy_bus bb_miiphy_buses[] = {
597         {
598                 .name = "board0",
599                 .init = mii_dummy_init,
600                 .mdio_active = mii_mdio_active,
601                 .mdio_tristate = mii_mdio_tristate,
602                 .set_mdio = mii_set_mdio,
603                 .get_mdio = mii_get_mdio,
604                 .set_mdc = mii_set_mdc,
605                 .delay = mii_delay,
606                 .priv = &fpga_mii[0],
607         },
608         {
609                 .name = "board1",
610                 .init = mii_dummy_init,
611                 .mdio_active = mii_mdio_active,
612                 .mdio_tristate = mii_mdio_tristate,
613                 .set_mdio = mii_set_mdio,
614                 .get_mdio = mii_get_mdio,
615                 .set_mdc = mii_set_mdc,
616                 .delay = mii_delay,
617                 .priv = &fpga_mii[1],
618         },
619         {
620                 .name = "board2",
621                 .init = mii_dummy_init,
622                 .mdio_active = mii_mdio_active,
623                 .mdio_tristate = mii_mdio_tristate,
624                 .set_mdio = mii_set_mdio,
625                 .get_mdio = mii_get_mdio,
626                 .set_mdc = mii_set_mdc,
627                 .delay = mii_delay,
628                 .priv = &fpga_mii[2],
629         },
630         {
631                 .name = "board3",
632                 .init = mii_dummy_init,
633                 .mdio_active = mii_mdio_active,
634                 .mdio_tristate = mii_mdio_tristate,
635                 .set_mdio = mii_set_mdio,
636                 .get_mdio = mii_get_mdio,
637                 .set_mdc = mii_set_mdc,
638                 .delay = mii_delay,
639                 .priv = &fpga_mii[3],
640         },
641 };
642
643 int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) /
644                           sizeof(bb_miiphy_buses[0]);
645
646 enum {
647         MIICMD_SET,
648         MIICMD_MODIFY,
649         MIICMD_VERIFY_VALUE,
650         MIICMD_WAIT_FOR_VALUE,
651 };
652
653 struct mii_setupcmd {
654         u8 token;
655         u8 reg;
656         u16 data;
657         u16 mask;
658         u32 timeout;
659 };
660
661 /*
662  * verify we are talking to a 88e1518
663  */
664 struct mii_setupcmd verify_88e1518[] = {
665         { MIICMD_SET, 22, 0x0000 },
666         { MIICMD_VERIFY_VALUE, 2, 0x0141, 0xffff },
667         { MIICMD_VERIFY_VALUE, 3, 0x0dd0, 0xfff0 },
668 };
669
670 /*
671  * workaround for erratum mentioned in 88E1518 release notes
672  */
673 struct mii_setupcmd fixup_88e1518[] = {
674         { MIICMD_SET, 22, 0x00ff },
675         { MIICMD_SET, 17, 0x214b },
676         { MIICMD_SET, 16, 0x2144 },
677         { MIICMD_SET, 17, 0x0c28 },
678         { MIICMD_SET, 16, 0x2146 },
679         { MIICMD_SET, 17, 0xb233 },
680         { MIICMD_SET, 16, 0x214d },
681         { MIICMD_SET, 17, 0xcc0c },
682         { MIICMD_SET, 16, 0x2159 },
683         { MIICMD_SET, 22, 0x00fb },
684         { MIICMD_SET,  7, 0xc00d },
685         { MIICMD_SET, 22, 0x0000 },
686 };
687
688 /*
689  * default initialization:
690  * - set RGMII receive timing to "receive clock transition when data stable"
691  * - set RGMII transmit timing to "transmit clock internally delayed"
692  * - set RGMII output impedance target to 78,8 Ohm
693  * - run output impedance calibration
694  * - set autonegotiation advertise to 1000FD only
695  */
696 struct mii_setupcmd default_88e1518[] = {
697         { MIICMD_SET, 22, 0x0002 },
698         { MIICMD_MODIFY, 21, 0x0030, 0x0030 },
699         { MIICMD_MODIFY, 25, 0x0000, 0x0003 },
700         { MIICMD_MODIFY, 24, 0x8000, 0x8000 },
701         { MIICMD_WAIT_FOR_VALUE, 24, 0x4000, 0x4000, 2000 },
702         { MIICMD_SET, 22, 0x0000 },
703         { MIICMD_MODIFY, 4, 0x0000, 0x01e0 },
704         { MIICMD_MODIFY, 9, 0x0200, 0x0300 },
705 };
706
707 /*
708  * turn off CLK125 for PHY daughterboard
709  */
710 struct mii_setupcmd ch1fix_88e1518[] = {
711         { MIICMD_SET, 22, 0x0002 },
712         { MIICMD_MODIFY, 16, 0x0006, 0x0006 },
713         { MIICMD_SET, 22, 0x0000 },
714 };
715
716 /*
717  * perform copper software reset
718  */
719 struct mii_setupcmd swreset_88e1518[] = {
720         { MIICMD_SET, 22, 0x0000 },
721         { MIICMD_MODIFY, 0, 0x8000, 0x8000 },
722         { MIICMD_WAIT_FOR_VALUE, 0, 0x0000, 0x8000, 2000 },
723 };
724
725 static int process_setupcmd(const char *bus, unsigned char addr,
726                             struct mii_setupcmd *setupcmd)
727 {
728         int res;
729         u8 reg = setupcmd->reg;
730         u16 data = setupcmd->data;
731         u16 mask = setupcmd->mask;
732         u32 timeout = setupcmd->timeout;
733         u16 orig_data;
734         unsigned long start;
735
736         debug("mii %s:%u reg %2u ", bus, addr, reg);
737
738         switch (setupcmd->token) {
739         case MIICMD_MODIFY:
740                 res = miiphy_read(bus, addr, reg, &orig_data);
741                 if (res)
742                         break;
743                 debug("is %04x. (value %04x mask %04x) ", orig_data, data,
744                       mask);
745                 data = (orig_data & ~mask) | (data & mask);
746         case MIICMD_SET:
747                 debug("=> %04x\n", data);
748                 res = miiphy_write(bus, addr, reg, data);
749                 break;
750         case MIICMD_VERIFY_VALUE:
751                 res = miiphy_read(bus, addr, reg, &orig_data);
752                 if (res)
753                         break;
754                 if ((orig_data & mask) != (data & mask))
755                         res = -1;
756                 debug("(value %04x mask %04x) == %04x? %s\n", data, mask,
757                       orig_data, res ? "FAIL" : "PASS");
758                 break;
759         case MIICMD_WAIT_FOR_VALUE:
760                 res = -1;
761                 start = get_timer(0);
762                 while ((res != 0) && (get_timer(start) < timeout)) {
763                         res = miiphy_read(bus, addr, reg, &orig_data);
764                         if (res)
765                                 continue;
766                         if ((orig_data & mask) != (data & mask))
767                                 res = -1;
768                 }
769                 debug("(value %04x mask %04x) == %04x? %s after %lu ms\n", data,
770                       mask, orig_data, res ? "FAIL" : "PASS",
771                       get_timer(start));
772                 break;
773         default:
774                 res = -1;
775                 break;
776         }
777
778         return res;
779 }
780
781 static int process_setup(const char *bus, unsigned char addr,
782                             struct mii_setupcmd *setupcmd, unsigned int count)
783 {
784         int res = 0;
785         unsigned int k;
786
787         for (k = 0; k < count; ++k) {
788                 res = process_setupcmd(bus, addr, &setupcmd[k]);
789                 if (res) {
790                         printf("mii cmd %u on bus %s addr %u failed, aborting setup",
791                                setupcmd[k].token, bus, addr);
792                         break;
793                 }
794         }
795
796         return res;
797 }
798
799 static int setup_88e1518(const char *bus, unsigned char addr)
800 {
801         int res;
802
803         res = process_setup(bus, addr,
804                             verify_88e1518, ARRAY_SIZE(verify_88e1518));
805         if (res)
806                 return res;
807
808         res = process_setup(bus, addr,
809                             fixup_88e1518, ARRAY_SIZE(fixup_88e1518));
810         if (res)
811                 return res;
812
813         res = process_setup(bus, addr,
814                             default_88e1518, ARRAY_SIZE(default_88e1518));
815         if (res)
816                 return res;
817
818         if (addr) {
819                 res = process_setup(bus, addr,
820                                     ch1fix_88e1518, ARRAY_SIZE(ch1fix_88e1518));
821                 if (res)
822                         return res;
823         }
824
825         res = process_setup(bus, addr,
826                             swreset_88e1518, ARRAY_SIZE(swreset_88e1518));
827         if (res)
828                 return res;
829
830         return 0;
831 }