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