]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/gdsys/405ep/iocon.c
board: iocon: Modify iocon hardware startup
[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                 /* Turn on Parade DP501 */
379                 pca9698_direction_output(0x20, 9, 1);
380
381                 ch0_rgmii2_present = !pca9698_get_value(0x20, 30);
382         }
383
384         /* wait for FPGA done */
385         for (k = 0; k < ARRAY_SIZE(mclink_controllers); ++k) {
386                 unsigned int ctr = 0;
387
388                 if (i2c_probe(mclink_controllers[k]))
389                         continue;
390
391                 while (!(pca953x_get_val(mclink_controllers[k])
392                        & MCFPGA_DONE)) {
393                         udelay(100000);
394                         if (ctr++ > 5) {
395                                 printf("no done for mclink_controller %d\n", k);
396                                 break;
397                         }
398                 }
399         }
400
401         if (!legacy && (feature_carrier_speed == CARRIER_SPEED_1G)) {
402                 miiphy_register(bb_miiphy_buses[0].name, bb_miiphy_read,
403                                 bb_miiphy_write);
404                 for (mux_ch = 0; mux_ch < MAX_MUX_CHANNELS; ++mux_ch) {
405                         if ((mux_ch == 1) && !ch0_rgmii2_present)
406                                 continue;
407
408                         setup_88e1518(bb_miiphy_buses[0].name, mux_ch);
409                 }
410         }
411
412         /* give slave-PLLs and Parade DP501 some time to be up and running */
413         udelay(500000);
414
415         mclink_fpgacount = CONFIG_SYS_MCLINK_MAX;
416         slaves = mclink_probe();
417         mclink_fpgacount = 0;
418
419         print_fpga_info(0, ch0_rgmii2_present);
420         osd_probe(0);
421
422         if (slaves <= 0)
423                 return 0;
424
425         mclink_fpgacount = slaves;
426
427         for (k = 1; k <= slaves; ++k) {
428                 FPGA_GET_REG(k, fpga_features, &fpga_features);
429                 feature_carrier_speed = fpga_features & (1<<4);
430
431                 print_fpga_info(k, false);
432                 osd_probe(k);
433                 if (feature_carrier_speed == CARRIER_SPEED_1G) {
434                         miiphy_register(bb_miiphy_buses[k].name,
435                                         bb_miiphy_read, bb_miiphy_write);
436                         setup_88e1518(bb_miiphy_buses[k].name, 0);
437                 }
438         }
439
440         return 0;
441 }
442
443 /*
444  * provide access to fpga gpios (for I2C bitbang)
445  * (these may look all too simple but make iocon.h much more readable)
446  */
447 void fpga_gpio_set(unsigned int bus, int pin)
448 {
449         FPGA_SET_REG(bus, gpio.set, pin);
450 }
451
452 void fpga_gpio_clear(unsigned int bus, int pin)
453 {
454         FPGA_SET_REG(bus, gpio.clear, pin);
455 }
456
457 int fpga_gpio_get(unsigned int bus, int pin)
458 {
459         u16 val;
460
461         FPGA_GET_REG(bus, gpio.read, &val);
462
463         return val & pin;
464 }
465
466 void gd405ep_init(void)
467 {
468         unsigned int k;
469
470         if (i2c_probe(0x20)) { /* i2c_probe returns 0 on success */
471                 for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k)
472                         gd->arch.fpga_state[k] |= FPGA_STATE_PLATFORM;
473         } else {
474                 pca9698_direction_output(0x20, 4, 1);
475         }
476 }
477
478 void gd405ep_set_fpga_reset(unsigned state)
479 {
480         int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
481
482         if (legacy) {
483                 if (state) {
484                         out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_RESET);
485                         out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_RESET);
486                 } else {
487                         out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_BOOT);
488                         out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_BOOT);
489                 }
490         } else {
491                 pca9698_set_value(0x20, 4, state ? 0 : 1);
492         }
493 }
494
495 void gd405ep_setup_hw(void)
496 {
497         /*
498          * set "startup-finished"-gpios
499          */
500         gpio_write_bit(21, 0);
501         gpio_write_bit(22, 1);
502 }
503
504 int gd405ep_get_fpga_done(unsigned fpga)
505 {
506         int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
507
508         if (legacy)
509                 return in_le16((void *)LATCH2_BASE)
510                        & CONFIG_SYS_FPGA_DONE(fpga);
511         else
512                 return pca9698_get_value(0x20, 20);
513 }
514
515 /*
516  * FPGA MII bitbang implementation
517  */
518
519 struct fpga_mii {
520         unsigned fpga;
521         int mdio;
522 } fpga_mii[] = {
523         { 0, 1},
524         { 1, 1},
525         { 2, 1},
526         { 3, 1},
527 };
528
529 static int mii_dummy_init(struct bb_miiphy_bus *bus)
530 {
531         return 0;
532 }
533
534 static int mii_mdio_active(struct bb_miiphy_bus *bus)
535 {
536         struct fpga_mii *fpga_mii = bus->priv;
537
538         if (fpga_mii->mdio)
539                 FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
540         else
541                 FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO);
542
543         return 0;
544 }
545
546 static int mii_mdio_tristate(struct bb_miiphy_bus *bus)
547 {
548         struct fpga_mii *fpga_mii = bus->priv;
549
550         FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
551
552         return 0;
553 }
554
555 static int mii_set_mdio(struct bb_miiphy_bus *bus, int v)
556 {
557         struct fpga_mii *fpga_mii = bus->priv;
558
559         if (v)
560                 FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
561         else
562                 FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO);
563
564         fpga_mii->mdio = v;
565
566         return 0;
567 }
568
569 static int mii_get_mdio(struct bb_miiphy_bus *bus, int *v)
570 {
571         u16 gpio;
572         struct fpga_mii *fpga_mii = bus->priv;
573
574         FPGA_GET_REG(fpga_mii->fpga, gpio.read, &gpio);
575
576         *v = ((gpio & GPIO_MDIO) != 0);
577
578         return 0;
579 }
580
581 static int mii_set_mdc(struct bb_miiphy_bus *bus, int v)
582 {
583         struct fpga_mii *fpga_mii = bus->priv;
584
585         if (v)
586                 FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDC);
587         else
588                 FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDC);
589
590         return 0;
591 }
592
593 static int mii_delay(struct bb_miiphy_bus *bus)
594 {
595         udelay(1);
596
597         return 0;
598 }
599
600 struct bb_miiphy_bus bb_miiphy_buses[] = {
601         {
602                 .name = "board0",
603                 .init = mii_dummy_init,
604                 .mdio_active = mii_mdio_active,
605                 .mdio_tristate = mii_mdio_tristate,
606                 .set_mdio = mii_set_mdio,
607                 .get_mdio = mii_get_mdio,
608                 .set_mdc = mii_set_mdc,
609                 .delay = mii_delay,
610                 .priv = &fpga_mii[0],
611         },
612         {
613                 .name = "board1",
614                 .init = mii_dummy_init,
615                 .mdio_active = mii_mdio_active,
616                 .mdio_tristate = mii_mdio_tristate,
617                 .set_mdio = mii_set_mdio,
618                 .get_mdio = mii_get_mdio,
619                 .set_mdc = mii_set_mdc,
620                 .delay = mii_delay,
621                 .priv = &fpga_mii[1],
622         },
623         {
624                 .name = "board2",
625                 .init = mii_dummy_init,
626                 .mdio_active = mii_mdio_active,
627                 .mdio_tristate = mii_mdio_tristate,
628                 .set_mdio = mii_set_mdio,
629                 .get_mdio = mii_get_mdio,
630                 .set_mdc = mii_set_mdc,
631                 .delay = mii_delay,
632                 .priv = &fpga_mii[2],
633         },
634         {
635                 .name = "board3",
636                 .init = mii_dummy_init,
637                 .mdio_active = mii_mdio_active,
638                 .mdio_tristate = mii_mdio_tristate,
639                 .set_mdio = mii_set_mdio,
640                 .get_mdio = mii_get_mdio,
641                 .set_mdc = mii_set_mdc,
642                 .delay = mii_delay,
643                 .priv = &fpga_mii[3],
644         },
645 };
646
647 int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) /
648                           sizeof(bb_miiphy_buses[0]);
649
650 enum {
651         MIICMD_SET,
652         MIICMD_MODIFY,
653         MIICMD_VERIFY_VALUE,
654         MIICMD_WAIT_FOR_VALUE,
655 };
656
657 struct mii_setupcmd {
658         u8 token;
659         u8 reg;
660         u16 data;
661         u16 mask;
662         u32 timeout;
663 };
664
665 /*
666  * verify we are talking to a 88e1518
667  */
668 struct mii_setupcmd verify_88e1518[] = {
669         { MIICMD_SET, 22, 0x0000 },
670         { MIICMD_VERIFY_VALUE, 2, 0x0141, 0xffff },
671         { MIICMD_VERIFY_VALUE, 3, 0x0dd0, 0xfff0 },
672 };
673
674 /*
675  * workaround for erratum mentioned in 88E1518 release notes
676  */
677 struct mii_setupcmd fixup_88e1518[] = {
678         { MIICMD_SET, 22, 0x00ff },
679         { MIICMD_SET, 17, 0x214b },
680         { MIICMD_SET, 16, 0x2144 },
681         { MIICMD_SET, 17, 0x0c28 },
682         { MIICMD_SET, 16, 0x2146 },
683         { MIICMD_SET, 17, 0xb233 },
684         { MIICMD_SET, 16, 0x214d },
685         { MIICMD_SET, 17, 0xcc0c },
686         { MIICMD_SET, 16, 0x2159 },
687         { MIICMD_SET, 22, 0x00fb },
688         { MIICMD_SET,  7, 0xc00d },
689         { MIICMD_SET, 22, 0x0000 },
690 };
691
692 /*
693  * default initialization:
694  * - set RGMII receive timing to "receive clock transition when data stable"
695  * - set RGMII transmit timing to "transmit clock internally delayed"
696  * - set RGMII output impedance target to 78,8 Ohm
697  * - run output impedance calibration
698  * - set autonegotiation advertise to 1000FD only
699  */
700 struct mii_setupcmd default_88e1518[] = {
701         { MIICMD_SET, 22, 0x0002 },
702         { MIICMD_MODIFY, 21, 0x0030, 0x0030 },
703         { MIICMD_MODIFY, 25, 0x0000, 0x0003 },
704         { MIICMD_MODIFY, 24, 0x8000, 0x8000 },
705         { MIICMD_WAIT_FOR_VALUE, 24, 0x4000, 0x4000, 2000 },
706         { MIICMD_SET, 22, 0x0000 },
707         { MIICMD_MODIFY, 4, 0x0000, 0x01e0 },
708         { MIICMD_MODIFY, 9, 0x0200, 0x0300 },
709 };
710
711 /*
712  * turn off CLK125 for PHY daughterboard
713  */
714 struct mii_setupcmd ch1fix_88e1518[] = {
715         { MIICMD_SET, 22, 0x0002 },
716         { MIICMD_MODIFY, 16, 0x0006, 0x0006 },
717         { MIICMD_SET, 22, 0x0000 },
718 };
719
720 /*
721  * perform copper software reset
722  */
723 struct mii_setupcmd swreset_88e1518[] = {
724         { MIICMD_SET, 22, 0x0000 },
725         { MIICMD_MODIFY, 0, 0x8000, 0x8000 },
726         { MIICMD_WAIT_FOR_VALUE, 0, 0x0000, 0x8000, 2000 },
727 };
728
729 static int process_setupcmd(const char *bus, unsigned char addr,
730                             struct mii_setupcmd *setupcmd)
731 {
732         int res;
733         u8 reg = setupcmd->reg;
734         u16 data = setupcmd->data;
735         u16 mask = setupcmd->mask;
736         u32 timeout = setupcmd->timeout;
737         u16 orig_data;
738         unsigned long start;
739
740         debug("mii %s:%u reg %2u ", bus, addr, reg);
741
742         switch (setupcmd->token) {
743         case MIICMD_MODIFY:
744                 res = miiphy_read(bus, addr, reg, &orig_data);
745                 if (res)
746                         break;
747                 debug("is %04x. (value %04x mask %04x) ", orig_data, data,
748                       mask);
749                 data = (orig_data & ~mask) | (data & mask);
750         case MIICMD_SET:
751                 debug("=> %04x\n", data);
752                 res = miiphy_write(bus, addr, reg, data);
753                 break;
754         case MIICMD_VERIFY_VALUE:
755                 res = miiphy_read(bus, addr, reg, &orig_data);
756                 if (res)
757                         break;
758                 if ((orig_data & mask) != (data & mask))
759                         res = -1;
760                 debug("(value %04x mask %04x) == %04x? %s\n", data, mask,
761                       orig_data, res ? "FAIL" : "PASS");
762                 break;
763         case MIICMD_WAIT_FOR_VALUE:
764                 res = -1;
765                 start = get_timer(0);
766                 while ((res != 0) && (get_timer(start) < timeout)) {
767                         res = miiphy_read(bus, addr, reg, &orig_data);
768                         if (res)
769                                 continue;
770                         if ((orig_data & mask) != (data & mask))
771                                 res = -1;
772                 }
773                 debug("(value %04x mask %04x) == %04x? %s after %lu ms\n", data,
774                       mask, orig_data, res ? "FAIL" : "PASS",
775                       get_timer(start));
776                 break;
777         default:
778                 res = -1;
779                 break;
780         }
781
782         return res;
783 }
784
785 static int process_setup(const char *bus, unsigned char addr,
786                             struct mii_setupcmd *setupcmd, unsigned int count)
787 {
788         int res = 0;
789         unsigned int k;
790
791         for (k = 0; k < count; ++k) {
792                 res = process_setupcmd(bus, addr, &setupcmd[k]);
793                 if (res) {
794                         printf("mii cmd %u on bus %s addr %u failed, aborting setup",
795                                setupcmd[k].token, bus, addr);
796                         break;
797                 }
798         }
799
800         return res;
801 }
802
803 static int setup_88e1518(const char *bus, unsigned char addr)
804 {
805         int res;
806
807         res = process_setup(bus, addr,
808                             verify_88e1518, ARRAY_SIZE(verify_88e1518));
809         if (res)
810                 return res;
811
812         res = process_setup(bus, addr,
813                             fixup_88e1518, ARRAY_SIZE(fixup_88e1518));
814         if (res)
815                 return res;
816
817         res = process_setup(bus, addr,
818                             default_88e1518, ARRAY_SIZE(default_88e1518));
819         if (res)
820                 return res;
821
822         if (addr) {
823                 res = process_setup(bus, addr,
824                                     ch1fix_88e1518, ARRAY_SIZE(ch1fix_88e1518));
825                 if (res)
826                         return res;
827         }
828
829         res = process_setup(bus, addr,
830                             swreset_88e1518, ARRAY_SIZE(swreset_88e1518));
831         if (res)
832                 return res;
833
834         return 0;
835 }