]> git.karo-electronics.de Git - karo-tx-uboot.git/blob - board/gdsys/405ep/iocon.c
9f84fb186900fbb19ef03efc7d66d40f29c5ce83
[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 enum {
34         UNITTYPE_MAIN_SERVER = 0,
35         UNITTYPE_MAIN_USER = 1,
36         UNITTYPE_VIDEO_SERVER = 2,
37         UNITTYPE_VIDEO_USER = 3,
38 };
39
40 enum {
41         HWVER_100 = 0,
42         HWVER_104 = 1,
43         HWVER_110 = 2,
44         HWVER_120 = 3,
45         HWVER_200 = 4,
46         HWVER_210 = 5,
47 };
48
49 enum {
50         FPGA_HWVER_200 = 0,
51         FPGA_HWVER_210 = 1,
52 };
53
54 enum {
55         COMPRESSION_NONE = 0,
56         COMPRESSION_TYPE1_DELTA = 1,
57         COMPRESSION_TYPE1_TYPE2_DELTA = 3,
58 };
59
60 enum {
61         AUDIO_NONE = 0,
62         AUDIO_TX = 1,
63         AUDIO_RX = 2,
64         AUDIO_RXTX = 3,
65 };
66
67 enum {
68         SYSCLK_147456 = 0,
69 };
70
71 enum {
72         RAM_DDR2_32 = 0,
73         RAM_DDR3_32 = 1,
74 };
75
76 enum {
77         MCFPGA_DONE = 1 << 0,
78         MCFPGA_INIT_N = 1 << 1,
79         MCFPGA_PROGRAM_N = 1 << 2,
80         MCFPGA_UPDATE_ENABLE_N = 1 << 3,
81         MCFPGA_RESET_N = 1 << 4,
82 };
83
84 enum {
85         GPIO_MDC = 1 << 14,
86         GPIO_MDIO = 1 << 15,
87 };
88
89 unsigned int mclink_fpgacount;
90 struct ihs_fpga *fpga_ptr[] = CONFIG_SYS_FPGA_PTR;
91
92 static int setup_88e1518(const char *bus, unsigned char addr);
93 static int verify_88e1518(const char *bus, unsigned char addr);
94
95 int fpga_set_reg(u32 fpga, u16 *reg, off_t regoff, u16 data)
96 {
97         int res;
98
99         switch (fpga) {
100         case 0:
101                 out_le16(reg, data);
102                 break;
103         default:
104                 res = mclink_send(fpga - 1, regoff, data);
105                 if (res < 0) {
106                         printf("mclink_send reg %02lx data %04x returned %d\n",
107                                regoff, data, res);
108                         return res;
109                 }
110                 break;
111         }
112
113         return 0;
114 }
115
116 int fpga_get_reg(u32 fpga, u16 *reg, off_t regoff, u16 *data)
117 {
118         int res;
119
120         switch (fpga) {
121         case 0:
122                 *data = in_le16(reg);
123                 break;
124         default:
125                 if (fpga > mclink_fpgacount)
126                         return -EINVAL;
127                 res = mclink_receive(fpga - 1, regoff, data);
128                 if (res < 0) {
129                         printf("mclink_receive reg %02lx returned %d\n",
130                                regoff, res);
131                         return res;
132                 }
133         }
134
135         return 0;
136 }
137
138 /*
139  * Check Board Identity:
140  */
141 int checkboard(void)
142 {
143         char *s = getenv("serial#");
144
145         puts("Board: ");
146
147         puts("IoCon");
148
149         if (s != NULL) {
150                 puts(", serial# ");
151                 puts(s);
152         }
153
154         puts("\n");
155
156         return 0;
157 }
158
159 static void print_fpga_info(unsigned int fpga)
160 {
161         u16 versions;
162         u16 fpga_version;
163         u16 fpga_features;
164         unsigned unit_type;
165         unsigned hardware_version;
166         unsigned feature_compression;
167         unsigned feature_osd;
168         unsigned feature_audio;
169         unsigned feature_sysclock;
170         unsigned feature_ramconfig;
171         unsigned feature_carriers;
172         unsigned feature_video_channels;
173         int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
174
175         FPGA_GET_REG(0, versions, &versions);
176         FPGA_GET_REG(0, fpga_version, &fpga_version);
177         FPGA_GET_REG(0, fpga_features, &fpga_features);
178
179         unit_type = (versions & 0xf000) >> 12;
180         feature_compression = (fpga_features & 0xe000) >> 13;
181         feature_osd = fpga_features & (1<<11);
182         feature_audio = (fpga_features & 0x0600) >> 9;
183         feature_sysclock = (fpga_features & 0x0180) >> 7;
184         feature_ramconfig = (fpga_features & 0x0060) >> 5;
185         feature_carriers = (fpga_features & 0x000c) >> 2;
186         feature_video_channels = fpga_features & 0x0003;
187
188         if (legacy)
189                 printf("legacy ");
190
191         switch (unit_type) {
192         case UNITTYPE_MAIN_USER:
193                 printf("Mainchannel");
194                 break;
195
196         case UNITTYPE_VIDEO_USER:
197                 printf("Videochannel");
198                 break;
199
200         default:
201                 printf("UnitType %d(not supported)", unit_type);
202                 break;
203         }
204
205         if (unit_type == UNITTYPE_MAIN_USER) {
206                 if (legacy)
207                         hardware_version =
208                                 (in_le16((void *)LATCH2_BASE)>>8) & 0x0f;
209                 else
210                         hardware_version =
211                                   (!!pca9698_get_value(0x20, 24) << 0)
212                                 | (!!pca9698_get_value(0x20, 25) << 1)
213                                 | (!!pca9698_get_value(0x20, 26) << 2)
214                                 | (!!pca9698_get_value(0x20, 27) << 3);
215                 switch (hardware_version) {
216                 case HWVER_100:
217                         printf(" HW-Ver 1.00,");
218                         break;
219
220                 case HWVER_104:
221                         printf(" HW-Ver 1.04,");
222                         break;
223
224                 case HWVER_110:
225                         printf(" HW-Ver 1.10,");
226                         break;
227
228                 case HWVER_120:
229                         printf(" HW-Ver 1.20-1.21,");
230                         break;
231
232                 case HWVER_200:
233                         printf(" HW-Ver 2.00,");
234                         break;
235
236                 case HWVER_210:
237                         printf(" HW-Ver 2.10,");
238                         break;
239
240                 default:
241                         printf(" HW-Ver %d(not supported),",
242                                hardware_version);
243                         break;
244                 }
245         }
246
247         if (unit_type == UNITTYPE_VIDEO_USER) {
248                 hardware_version = versions & 0x000f;
249                 switch (hardware_version) {
250                 case FPGA_HWVER_200:
251                         printf(" HW-Ver 2.00,");
252                         break;
253
254                 case FPGA_HWVER_210:
255                         printf(" HW-Ver 2.10,");
256                         break;
257
258                 default:
259                         printf(" HW-Ver %d(not supported),",
260                                hardware_version);
261                         break;
262                 }
263         }
264
265         printf(" FPGA V %d.%02d\n       features:",
266                fpga_version / 100, fpga_version % 100);
267
268
269         switch (feature_compression) {
270         case COMPRESSION_NONE:
271                 printf(" no compression");
272                 break;
273
274         case COMPRESSION_TYPE1_DELTA:
275                 printf(" type1-deltacompression");
276                 break;
277
278         case COMPRESSION_TYPE1_TYPE2_DELTA:
279                 printf(" type1-deltacompression, type2-inlinecompression");
280                 break;
281
282         default:
283                 printf(" compression %d(not supported)", feature_compression);
284                 break;
285         }
286
287         printf(", %sosd", feature_osd ? "" : "no ");
288
289         switch (feature_audio) {
290         case AUDIO_NONE:
291                 printf(", no audio");
292                 break;
293
294         case AUDIO_TX:
295                 printf(", audio tx");
296                 break;
297
298         case AUDIO_RX:
299                 printf(", audio rx");
300                 break;
301
302         case AUDIO_RXTX:
303                 printf(", audio rx+tx");
304                 break;
305
306         default:
307                 printf(", audio %d(not supported)", feature_audio);
308                 break;
309         }
310
311         puts(",\n       ");
312
313         switch (feature_sysclock) {
314         case SYSCLK_147456:
315                 printf("clock 147.456 MHz");
316                 break;
317
318         default:
319                 printf("clock %d(not supported)", feature_sysclock);
320                 break;
321         }
322
323         switch (feature_ramconfig) {
324         case RAM_DDR2_32:
325                 printf(", RAM 32 bit DDR2");
326                 break;
327
328         case RAM_DDR3_32:
329                 printf(", RAM 32 bit DDR3");
330                 break;
331
332         default:
333                 printf(", RAM %d(not supported)", feature_ramconfig);
334                 break;
335         }
336
337         printf(", %d carrier(s)", feature_carriers);
338
339         printf(", %d video channel(s)\n", feature_video_channels);
340 }
341
342 int last_stage_init(void)
343 {
344         int slaves;
345         unsigned int k;
346         unsigned char mclink_controllers[] = { 0x24, 0x25, 0x26 };
347         int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
348
349         print_fpga_info(0);
350         osd_probe(0);
351
352         /* wait for FPGA done */
353         for (k = 0; k < ARRAY_SIZE(mclink_controllers); ++k) {
354                 unsigned int ctr = 0;
355
356                 if (i2c_probe(mclink_controllers[k]))
357                         continue;
358
359                 while (!(pca953x_get_val(mclink_controllers[k])
360                        & MCFPGA_DONE)) {
361                         udelay(100000);
362                         if (ctr++ > 5) {
363                                 printf("no done for mclink_controller %d\n", k);
364                                 break;
365                         }
366                 }
367         }
368
369         if (!legacy) {
370                 miiphy_register(bb_miiphy_buses[0].name, bb_miiphy_read,
371                                 bb_miiphy_write);
372                 if (!verify_88e1518(bb_miiphy_buses[0].name, 0)) {
373                         printf("Fixup 88e1518 erratum on %s\n",
374                                bb_miiphy_buses[0].name);
375                         setup_88e1518(bb_miiphy_buses[0].name, 0);
376                 }
377         }
378
379         /* wait for slave-PLLs to be up and running */
380         udelay(500000);
381
382         mclink_fpgacount = CONFIG_SYS_MCLINK_MAX;
383         slaves = mclink_probe();
384         mclink_fpgacount = 0;
385
386         if (slaves <= 0)
387                 return 0;
388
389         mclink_fpgacount = slaves;
390
391         for (k = 1; k <= slaves; ++k) {
392                 print_fpga_info(k);
393                 osd_probe(k);
394                 miiphy_register(bb_miiphy_buses[k].name,
395                                 bb_miiphy_read, bb_miiphy_write);
396                 if (!verify_88e1518(bb_miiphy_buses[k].name, 0)) {
397                         printf("Fixup 88e1518 erratum on %s\n",
398                                bb_miiphy_buses[k].name);
399                         setup_88e1518(bb_miiphy_buses[k].name, 0);
400                 }
401         }
402
403         return 0;
404 }
405
406 /*
407  * provide access to fpga gpios (for I2C bitbang)
408  * (these may look all too simple but make iocon.h much more readable)
409  */
410 void fpga_gpio_set(unsigned int bus, int pin)
411 {
412         FPGA_SET_REG(bus, gpio.set, pin);
413 }
414
415 void fpga_gpio_clear(unsigned int bus, int pin)
416 {
417         FPGA_SET_REG(bus, gpio.clear, pin);
418 }
419
420 int fpga_gpio_get(unsigned int bus, int pin)
421 {
422         u16 val;
423
424         FPGA_GET_REG(bus, gpio.read, &val);
425
426         return val & pin;
427 }
428
429 void gd405ep_init(void)
430 {
431         unsigned int k;
432
433         if (i2c_probe(0x20)) { /* i2c_probe returns 0 on success */
434                 for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k)
435                         gd->arch.fpga_state[k] |= FPGA_STATE_PLATFORM;
436         } else {
437                 pca9698_direction_output(0x20, 4, 1);
438         }
439 }
440
441 void gd405ep_set_fpga_reset(unsigned state)
442 {
443         int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
444
445         if (legacy) {
446                 if (state) {
447                         out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_RESET);
448                         out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_RESET);
449                 } else {
450                         out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_BOOT);
451                         out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_BOOT);
452                 }
453         } else {
454                 pca9698_set_value(0x20, 4, state ? 0 : 1);
455         }
456 }
457
458 void gd405ep_setup_hw(void)
459 {
460         /*
461          * set "startup-finished"-gpios
462          */
463         gpio_write_bit(21, 0);
464         gpio_write_bit(22, 1);
465 }
466
467 int gd405ep_get_fpga_done(unsigned fpga)
468 {
469         int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
470
471         if (legacy)
472                 return in_le16((void *)LATCH2_BASE)
473                        & CONFIG_SYS_FPGA_DONE(fpga);
474         else
475                 return pca9698_get_value(0x20, 20);
476 }
477
478 /*
479  * FPGA MII bitbang implementation
480  */
481
482 struct fpga_mii {
483         unsigned fpga;
484         int mdio;
485 } fpga_mii[] = {
486         { 0, 1},
487         { 1, 1},
488         { 2, 1},
489         { 3, 1},
490 };
491
492 static int mii_dummy_init(struct bb_miiphy_bus *bus)
493 {
494         return 0;
495 }
496
497 static int mii_mdio_active(struct bb_miiphy_bus *bus)
498 {
499         struct fpga_mii *fpga_mii = bus->priv;
500
501         if (fpga_mii->mdio)
502                 FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
503         else
504                 FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO);
505
506         return 0;
507 }
508
509 static int mii_mdio_tristate(struct bb_miiphy_bus *bus)
510 {
511         struct fpga_mii *fpga_mii = bus->priv;
512
513         FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
514
515         return 0;
516 }
517
518 static int mii_set_mdio(struct bb_miiphy_bus *bus, int v)
519 {
520         struct fpga_mii *fpga_mii = bus->priv;
521
522         if (v)
523                 FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
524         else
525                 FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO);
526
527         fpga_mii->mdio = v;
528
529         return 0;
530 }
531
532 static int mii_get_mdio(struct bb_miiphy_bus *bus, int *v)
533 {
534         u16 gpio;
535         struct fpga_mii *fpga_mii = bus->priv;
536
537         FPGA_GET_REG(fpga_mii->fpga, gpio.read, &gpio);
538
539         *v = ((gpio & GPIO_MDIO) != 0);
540
541         return 0;
542 }
543
544 static int mii_set_mdc(struct bb_miiphy_bus *bus, int v)
545 {
546         struct fpga_mii *fpga_mii = bus->priv;
547
548         if (v)
549                 FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDC);
550         else
551                 FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDC);
552
553         return 0;
554 }
555
556 static int mii_delay(struct bb_miiphy_bus *bus)
557 {
558         udelay(1);
559
560         return 0;
561 }
562
563 struct bb_miiphy_bus bb_miiphy_buses[] = {
564         {
565                 .name = "trans1",
566                 .init = mii_dummy_init,
567                 .mdio_active = mii_mdio_active,
568                 .mdio_tristate = mii_mdio_tristate,
569                 .set_mdio = mii_set_mdio,
570                 .get_mdio = mii_get_mdio,
571                 .set_mdc = mii_set_mdc,
572                 .delay = mii_delay,
573                 .priv = &fpga_mii[0],
574         },
575         {
576                 .name = "trans2",
577                 .init = mii_dummy_init,
578                 .mdio_active = mii_mdio_active,
579                 .mdio_tristate = mii_mdio_tristate,
580                 .set_mdio = mii_set_mdio,
581                 .get_mdio = mii_get_mdio,
582                 .set_mdc = mii_set_mdc,
583                 .delay = mii_delay,
584                 .priv = &fpga_mii[1],
585         },
586         {
587                 .name = "trans3",
588                 .init = mii_dummy_init,
589                 .mdio_active = mii_mdio_active,
590                 .mdio_tristate = mii_mdio_tristate,
591                 .set_mdio = mii_set_mdio,
592                 .get_mdio = mii_get_mdio,
593                 .set_mdc = mii_set_mdc,
594                 .delay = mii_delay,
595                 .priv = &fpga_mii[2],
596         },
597         {
598                 .name = "trans4",
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[3],
607         },
608 };
609
610 int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) /
611                           sizeof(bb_miiphy_buses[0]);
612
613 /*
614  * Workaround for erratum mentioned in 88E1518 release notes
615  */
616
617 static int verify_88e1518(const char *bus, unsigned char addr)
618 {
619         u16 phy_id1, phy_id2;
620
621         if (miiphy_read(bus, addr, 2, &phy_id1) ||
622             miiphy_read(bus, addr, 3, &phy_id2)) {
623                 printf("Error reading from the PHY addr=%02x\n", addr);
624                 return -EIO;
625         }
626
627         if ((phy_id1 != 0x0141) || ((phy_id2 & 0xfff0) != 0x0dd0))
628                 return -EINVAL;
629
630         return 0;
631 }
632
633 struct regfix_88e1518 {
634         u8 reg;
635         u16 data;
636 } regfix_88e1518[] = {
637         { 22, 0x00ff },
638         { 17, 0x214b },
639         { 16, 0x2144 },
640         { 17, 0x0c28 },
641         { 16, 0x2146 },
642         { 17, 0xb233 },
643         { 16, 0x214d },
644         { 17, 0xcc0c },
645         { 16, 0x2159 },
646         { 22, 0x00fb },
647         {  7, 0xc00d },
648         { 22, 0x0000 },
649 };
650
651 static int setup_88e1518(const char *bus, unsigned char addr)
652 {
653         unsigned int k;
654
655         for (k = 0; k < ARRAY_SIZE(regfix_88e1518); ++k) {
656                 if (miiphy_write(bus, addr,
657                                  regfix_88e1518[k].reg,
658                                  regfix_88e1518[k].data)) {
659                         printf("Error writing to the PHY addr=%02x\n", addr);
660                         return -1;
661                 }
662         }
663
664         return 0;
665 }