brdsetup.c revision 1.35 1 /* $NetBSD: brdsetup.c,v 1.35 2014/08/08 21:18:10 joerg Exp $ */
2
3 /*-
4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Tohru Nishimura.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <sys/param.h>
33
34 #include <powerpc/psl.h>
35 #include <powerpc/oea/spr.h>
36
37 #include <lib/libsa/stand.h>
38 #include <lib/libsa/net.h>
39 #include <lib/libkern/libkern.h>
40
41 #include <machine/bootinfo.h>
42
43 #include "globals.h"
44
45 #define BRD_DECL(xxx) \
46 void xxx ## setup(struct brdprop *); \
47 void xxx ## brdfix(struct brdprop *); \
48 void xxx ## pcifix(struct brdprop *); \
49 void xxx ## launch(struct brdprop *); \
50 void xxx ## reset(void)
51
52 BRD_DECL(mot);
53 BRD_DECL(enc);
54 BRD_DECL(kuro);
55 BRD_DECL(syno);
56 BRD_DECL(qnap);
57 BRD_DECL(iomega);
58 BRD_DECL(dlink);
59 BRD_DECL(nhnas);
60 BRD_DECL(kurot4);
61
62 static void brdfixup(void);
63 static void setup(void);
64 static void send_iomega(int, int, int, int, int, int);
65 static inline uint32_t mfmsr(void);
66 static inline void mtmsr(uint32_t);
67 static inline uint32_t cputype(void);
68 static inline u_quad_t mftb(void);
69 static void init_uart(unsigned, unsigned, uint8_t);
70 static void send_sat(char *);
71 static unsigned mpc107memsize(void);
72
73 /* UART registers */
74 #define RBR 0
75 #define THR 0
76 #define DLB 0
77 #define DMB 1
78 #define IER 1
79 #define FCR 2
80 #define LCR 3
81 #define LCR_DLAB 0x80
82 #define LCR_PEVEN 0x18
83 #define LCR_PNONE 0x00
84 #define LCR_8BITS 0x03
85 #define MCR 4
86 #define MCR_RTS 0x02
87 #define MCR_DTR 0x01
88 #define LSR 5
89 #define LSR_THRE 0x20
90 #define LSR_DRDY 0x01
91 #define DCR 0x11
92 #define UART_READ(base, r) in8(base + (r))
93 #define UART_WRITE(base, r, v) out8(base + (r), (v))
94
95 /* MPC106 and MPC824x PCI bridge memory configuration */
96 #define MPC106_MEMSTARTADDR1 0x80
97 #define MPC106_EXTMEMSTARTADDR1 0x88
98 #define MPC106_MEMENDADDR1 0x90
99 #define MPC106_EXTMEMENDADDR1 0x98
100 #define MPC106_MEMEN 0xa0
101
102 /* Iomega StorCenter MC68HC908 microcontroller data packet */
103 #define IOMEGA_POWER 0
104 #define IOMEGA_LED 1
105 #define IOMEGA_FLASH_RATE 2
106 #define IOMEGA_FAN 3
107 #define IOMEGA_HIGH_TEMP 4
108 #define IOMEGA_LOW_TEMP 5
109 #define IOMEGA_ID 6
110 #define IOMEGA_CHECKSUM 7
111 #define IOMEGA_PACKETSIZE 8
112
113 /* NH230/231 GPIO */
114 #define NHGPIO_WRITE(x) *((uint8_t *)0x70000000) = x
115
116 static struct brdprop brdlist[] = {
117 {
118 "sandpoint",
119 "Sandpoint X3",
120 BRD_SANDPOINTX3,
121 0,
122 "com", 0x3f8, 115200,
123 motsetup, motbrdfix, motpcifix, NULL, NULL },
124 {
125 "encpp1",
126 "EnCore PP1",
127 BRD_ENCOREPP1,
128 0,
129 "com", 0x3f8, 115200,
130 encsetup, encbrdfix, encpcifix, NULL, NULL },
131 {
132 "kurobox",
133 "KuroBox",
134 BRD_KUROBOX,
135 0,
136 "eumb", 0x4600, 57600,
137 kurosetup, kurobrdfix, NULL, NULL, kuroreset },
138 {
139 "synology",
140 "Synology CS/DS/RS",
141 BRD_SYNOLOGY,
142 0,
143 "eumb", 0x4500, 115200,
144 synosetup, synobrdfix, synopcifix, synolaunch, synoreset },
145 {
146 "qnap",
147 "QNAP TS",
148 BRD_QNAPTS,
149 33164691, /* Linux source says 33000000, but the Synology */
150 /* clock value delivers a much better precision. */
151 "eumb", 0x4500, 115200,
152 NULL, qnapbrdfix, NULL, NULL, qnapreset },
153 {
154 "iomega",
155 "IOMEGA StorCenter G2",
156 BRD_STORCENTER,
157 0,
158 "eumb", 0x4500, 115200,
159 NULL, iomegabrdfix, NULL, NULL, iomegareset },
160 {
161 "dlink",
162 "D-Link DSM-G600",
163 BRD_DLINKDSM,
164 33000000,
165 "eumb", 0x4500, 9600,
166 NULL, dlinkbrdfix, NULL, NULL, NULL },
167 {
168 "nhnas",
169 "Netronix NH-230/231",
170 BRD_NH230NAS,
171 33000000,
172 "eumb", 0x4500, 9600,
173 NULL, nhnasbrdfix, NULL, NULL, nhnasreset },
174 {
175 "kurot4",
176 "KuroBox/T4",
177 BRD_KUROBOXT4,
178 32768000,
179 "eumb", 0x4600, 57600,
180 NULL, kurot4brdfix, NULL, NULL, NULL },
181 {
182 "unknown",
183 "Unknown board",
184 BRD_UNKNOWN,
185 0,
186 "eumb", 0x4500, 115200,
187 NULL, NULL, NULL, NULL, NULL }, /* must be the last */
188 };
189
190 static struct brdprop *brdprop;
191 static uint32_t ticks_per_sec, ns_per_tick;
192
193 const unsigned dcache_line_size = 32; /* 32B linesize */
194 const unsigned dcache_range_size = 4 * 1024; /* 16KB / 4-way */
195
196 unsigned uart1base; /* console */
197 unsigned uart2base; /* optional satellite processor */
198
199 void brdsetup(void); /* called by entry.S */
200
201 void
202 brdsetup(void)
203 {
204 static uint8_t pci_to_memclk[] = {
205 30, 30, 10, 10, 20, 10, 10, 10,
206 10, 20, 20, 15, 20, 15, 20, 30,
207 30, 40, 15, 40, 20, 25, 20, 40,
208 25, 20, 10, 20, 15, 15, 20, 00
209 };
210 static uint8_t mem_to_cpuclk[] = {
211 25, 30, 45, 20, 20, 00, 10, 30,
212 30, 20, 45, 30, 25, 35, 30, 35,
213 20, 25, 20, 30, 35, 40, 40, 20,
214 30, 25, 40, 30, 30, 25, 35, 00
215 };
216 char *consname;
217 int consport;
218 uint32_t extclk;
219 unsigned pchb, pcib, dev11, dev12, dev13, dev15, dev16, val;
220 extern struct btinfo_memory bi_mem;
221 extern struct btinfo_console bi_cons;
222 extern struct btinfo_clock bi_clk;
223 extern struct btinfo_prodfamily bi_fam;
224
225 /*
226 * CHRP specification "Map-B" BAT012 layout
227 * BAT0 0000-0000 (256MB) SDRAM
228 * BAT1 8000-0000 (256MB) PCI mem space
229 * BAT2 fc00-0000 (64MB) EUMB, PCI I/O space, misc devs, flash
230 *
231 * EUMBBAR is at fc00-0000.
232 */
233 pchb = pcimaketag(0, 0, 0);
234 pcicfgwrite(pchb, 0x78, 0xfc000000);
235
236 brdtype = BRD_UNKNOWN;
237 extclk = EXT_CLK_FREQ; /* usually 33MHz */
238 busclock = 0;
239
240 dev11 = pcimaketag(0, 11, 0);
241 dev12 = pcimaketag(0, 12, 0);
242 dev13 = pcimaketag(0, 13, 0);
243 dev15 = pcimaketag(0, 15, 0);
244 dev16 = pcimaketag(0, 16, 0);
245
246 if (pcifinddev(0x10ad, 0x0565, &pcib) == 0) {
247 /* WinBond 553 southbridge at dev 11 */
248 brdtype = BRD_SANDPOINTX3;
249 }
250 else if (pcifinddev(0x1106, 0x0686, &pcib) == 0) {
251 /* VIA 686B southbridge at dev 22 */
252 brdtype = BRD_ENCOREPP1;
253 }
254 else if (PCI_CLASS(pcicfgread(dev11, PCI_CLASS_REG)) == PCI_CLASS_ETH) {
255 /* ADMtek AN985 (tlp) or RealTek 8169S (re) at dev 11 */
256 if (PCI_VENDOR(pcicfgread(dev12, PCI_ID_REG)) != 0x1095)
257 brdtype = BRD_KUROBOX;
258 else
259 brdtype = BRD_KUROBOXT4;
260 }
261 else if (PCI_VENDOR(pcicfgread(dev15, PCI_ID_REG)) == 0x11ab) {
262 /* SKnet/Marvell (sk) at dev 15 */
263 brdtype = BRD_SYNOLOGY;
264 }
265 else if (PCI_VENDOR(pcicfgread(dev13, PCI_ID_REG)) == 0x1106) {
266 /* VIA 6410 (viaide) at dev 13 */
267 brdtype = BRD_STORCENTER;
268 }
269 else if (PCI_VENDOR(pcicfgread(dev16, PCI_ID_REG)) == 0x1191) {
270 /* ACARD ATP865 (acardide) at dev 16 */
271 brdtype = BRD_DLINKDSM;
272 }
273 else if (PCI_VENDOR(pcicfgread(dev16, PCI_ID_REG)) == 0x1283
274 || PCI_VENDOR(pcicfgread(dev16, PCI_ID_REG)) == 0x1095) {
275 /* ITE (iteide) or SiI (satalink) at dev 16 */
276 brdtype = BRD_NH230NAS;
277 }
278 else if (PCI_VENDOR(pcicfgread(dev15, PCI_ID_REG)) == 0x8086
279 || PCI_VENDOR(pcicfgread(dev15, PCI_ID_REG)) == 0x10ec) {
280 /* Intel (wm) or RealTek (re) at dev 15 */
281 brdtype = BRD_QNAPTS;
282 }
283
284 brdprop = brd_lookup(brdtype);
285
286 /* brd dependent adjustments */
287 setup();
288
289 /* determine clock frequencies */
290 if (brdprop->extclk != 0)
291 extclk = brdprop->extclk;
292 if (busclock == 0) {
293 if (cputype() == MPC8245) {
294 /* PLL_CFG from PCI host bridge register 0xe2 */
295 val = pcicfgread(pchb, 0xe0);
296 busclock = (extclk *
297 pci_to_memclk[(val >> 19) & 0x1f] + 10) / 10;
298 /* PLLRATIO from HID1 */
299 asm volatile ("mfspr %0,1009" : "=r"(val));
300 cpuclock = ((uint64_t)busclock *
301 mem_to_cpuclk[val >> 27] + 10) / 10;
302 } else
303 busclock = 100000000; /* 100MHz bus clock default */
304 }
305 ticks_per_sec = busclock >> 2;
306 ns_per_tick = 1000000000 / ticks_per_sec;
307
308 /* now prepare serial console */
309 consname = brdprop->consname;
310 consport = brdprop->consport;
311 if (strcmp(consname, "eumb") == 0) {
312 uart1base = 0xfc000000 + consport; /* 0x4500, 0x4600 */
313 UART_WRITE(uart1base, DCR, 0x01); /* enable DUART mode */
314 uart2base = uart1base ^ 0x0300;
315 } else
316 uart1base = 0xfe000000 + consport; /* 0x3f8, 0x2f8 */
317
318 /* more brd adjustments */
319 brdfixup();
320
321 bi_mem.memsize = mpc107memsize();
322 snprintf(bi_cons.devname, sizeof(bi_cons.devname), "%s", consname);
323 bi_cons.addr = consport;
324 bi_cons.speed = brdprop->consspeed;
325 bi_clk.ticks_per_sec = ticks_per_sec;
326 snprintf(bi_fam.name, sizeof(bi_fam.name), "%s", brdprop->family);
327 }
328
329 struct brdprop *
330 brd_lookup(int brd)
331 {
332 u_int i;
333
334 for (i = 0; i < sizeof(brdlist)/sizeof(brdlist[0]); i++) {
335 if (brdlist[i].brdtype == brd)
336 return &brdlist[i];
337 }
338 return &brdlist[i - 1];
339 }
340
341 static void
342 setup()
343 {
344
345 if (brdprop->setup == NULL)
346 return;
347 (*brdprop->setup)(brdprop);
348 }
349
350 static void
351 brdfixup()
352 {
353
354 if (brdprop->brdfix == NULL)
355 return;
356 (*brdprop->brdfix)(brdprop);
357 }
358
359 void
360 pcifixup()
361 {
362
363 if (brdprop->pcifix == NULL)
364 return;
365 (*brdprop->pcifix)(brdprop);
366 }
367
368 void
369 launchfixup()
370 {
371
372 if (brdprop->launch == NULL)
373 return;
374 (*brdprop->launch)(brdprop);
375 }
376
377 void
378 encsetup(struct brdprop *brd)
379 {
380
381 #ifdef COSNAME
382 brd->consname = CONSNAME;
383 #endif
384 #ifdef CONSPORT
385 brd->consport = CONSPORT;
386 #endif
387 #ifdef CONSSPEED
388 brd->consspeed = CONSSPEED;
389 #endif
390 }
391
392 void
393 encbrdfix(struct brdprop *brd)
394 {
395 unsigned ac97, ide, pcib, pmgt, usb12, usb34, val;
396
397 /*
398 * VIA82C686B Southbridge
399 * 0.22.0 1106.0686 PCI-ISA bridge
400 * 0.22.1 1106.0571 IDE (viaide)
401 * 0.22.2 1106.3038 USB 0/1 (uhci)
402 * 0.22.3 1106.3038 USB 2/3 (uhci)
403 * 0.22.4 1106.3057 power management
404 * 0.22.5 1106.3058 AC97 (auvia)
405 */
406 pcib = pcimaketag(0, 22, 0);
407 ide = pcimaketag(0, 22, 1);
408 usb12 = pcimaketag(0, 22, 2);
409 usb34 = pcimaketag(0, 22, 3);
410 pmgt = pcimaketag(0, 22, 4);
411 ac97 = pcimaketag(0, 22, 5);
412
413 #define CFG(i,v) do { \
414 *(volatile unsigned char *)(0xfe000000 + 0x3f0) = (i); \
415 *(volatile unsigned char *)(0xfe000000 + 0x3f1) = (v); \
416 } while (0)
417 val = pcicfgread(pcib, 0x84);
418 val |= (02 << 8);
419 pcicfgwrite(pcib, 0x84, val);
420 CFG(0xe2, 0x0f); /* use COM1/2, don't use FDC/LPT */
421 val = pcicfgread(pcib, 0x84);
422 val &= ~(02 << 8);
423 pcicfgwrite(pcib, 0x84, val);
424
425 /* route pin C to i8259 IRQ 5, pin D to 11 */
426 val = pcicfgread(pcib, 0x54);
427 val = (val & 0xff) | 0xb0500000; /* Dx CB Ax xS */
428 pcicfgwrite(pcib, 0x54, val);
429
430 /* enable EISA ELCR1 (0x4d0) and ELCR2 (0x4d1) */
431 val = pcicfgread(pcib, 0x44);
432 val = val | 0x20000000;
433 pcicfgwrite(pcib, 0x44, val);
434
435 /* select level trigger for IRQ 5/11 at ELCR1/2 */
436 *(volatile uint8_t *)0xfe0004d0 = 0x20; /* bit 5 */
437 *(volatile uint8_t *)0xfe0004d1 = 0x08; /* bit 11 */
438
439 /* USB and AC97 are hardwired with pin D and C */
440 val = pcicfgread(usb12, 0x3c) &~ 0xff;
441 val |= 11;
442 pcicfgwrite(usb12, 0x3c, val);
443 val = pcicfgread(usb34, 0x3c) &~ 0xff;
444 val |= 11;
445 pcicfgwrite(usb34, 0x3c, val);
446 val = pcicfgread(ac97, 0x3c) &~ 0xff;
447 val |= 5;
448 pcicfgwrite(ac97, 0x3c, val);
449
450 (void) pcicfgread(ide, 0x08);
451 (void) pcicfgread(pmgt, 0x08);
452 }
453
454 void
455 encpcifix(struct brdprop *brd)
456 {
457 unsigned ide, irq, net, pcib, steer, val;
458
459 #define STEER(v, b) (((v) & (b)) ? "edge" : "level")
460 pcib = pcimaketag(0, 22, 0);
461 ide = pcimaketag(0, 22, 1);
462 net = pcimaketag(0, 25, 0);
463
464 /*
465 * //// VIA PIRQ ////
466 * 0x57/56/55/54 - Dx CB Ax xS
467 */
468 val = pcicfgread(pcib, 0x54); /* Dx CB Ax xs */
469 steer = val & 0xf;
470 irq = (val >> 12) & 0xf; /* 15:12 */
471 if (irq) {
472 printf("pin A -> irq %d, %s\n",
473 irq, STEER(steer, 0x1));
474 }
475 irq = (val >> 16) & 0xf; /* 19:16 */
476 if (irq) {
477 printf("pin B -> irq %d, %s\n",
478 irq, STEER(steer, 0x2));
479 }
480 irq = (val >> 20) & 0xf; /* 23:20 */
481 if (irq) {
482 printf("pin C -> irq %d, %s\n",
483 irq, STEER(steer, 0x4));
484 }
485 irq = (val >> 28); /* 31:28 */
486 if (irq) {
487 printf("pin D -> irq %d, %s\n",
488 irq, STEER(steer, 0x8));
489 }
490 #if 0
491 /*
492 * //// IDE fixup ////
493 * - "native mode" (ide 0x09)
494 */
495
496 /* ide: 0x09 - programming interface; 1000'SsPp */
497 val = pcicfgread(ide, 0x08) & 0xffff00ff;
498 pcicfgwrite(ide, 0x08, val | (0x8f << 8));
499
500 /* ide: 0x10-20 - leave them PCI memory space assigned */
501 #else
502 /*
503 * //// IDE fixup ////
504 * - "compatiblity mode" (ide 0x09)
505 * - remove PCI pin assignment (ide 0x3d)
506 */
507
508 /* ide: 0x09 - programming interface; 1000'SsPp */
509 val = pcicfgread(ide, 0x08) & 0xffff00ff;
510 val |= (0x8a << 8);
511 pcicfgwrite(ide, 0x08, val);
512
513 /* ide: 0x10-20 */
514 /*
515 * experiment shows writing ide: 0x09 changes these
516 * register behaviour. The pcicfgwrite() above writes
517 * 0x8a at ide: 0x09 to make sure legacy IDE. Then
518 * reading BAR0-3 is to return value 0s even though
519 * pcisetup() has written range assignments. Value
520 * overwrite makes no effect. Having 0x8f for native
521 * PCIIDE doesn't change register values and brings no
522 * weirdness.
523 */
524
525 /* ide: 0x3d/3c - turn off PCI pin */
526 val = pcicfgread(ide, 0x3c) & 0xffff00ff;
527 pcicfgwrite(ide, 0x3c, val);
528 #endif
529 /*
530 * //// USBx2, audio, and modem fixup ////
531 * - disable USB #0 and #1 (pcib 0x48 and 0x85)
532 * - disable AC97 audio and MC97 modem (pcib 0x85)
533 */
534
535 /* pcib: 0x48 - disable USB #0 at function 2 */
536 val = pcicfgread(pcib, 0x48);
537 pcicfgwrite(pcib, 0x48, val | 04);
538
539 /* pcib: 0x85 - disable USB #1 at function 3 */
540 /* pcib: 0x85 - disable AC97/MC97 at function 5/6 */
541 val = pcicfgread(pcib, 0x84);
542 pcicfgwrite(pcib, 0x84, val | 0x1c00);
543
544 /*
545 * //// fxp fixup ////
546 * - use PCI pin A line 25 (fxp 0x3d/3c)
547 */
548 /* 0x3d/3c - PCI pin/line */
549 val = pcicfgread(net, 0x3c) & 0xffff0000;
550 val |= (('A' - '@') << 8) | 25;
551 pcicfgwrite(net, 0x3c, val);
552 }
553
554 void
555 motsetup(struct brdprop *brd)
556 {
557
558 #ifdef COSNAME
559 brd->consname = CONSNAME;
560 #endif
561 #ifdef CONSPORT
562 brd->consport = CONSPORT;
563 #endif
564 #ifdef CONSSPEED
565 brd->consspeed = CONSSPEED;
566 #endif
567 }
568
569 void
570 motbrdfix(struct brdprop *brd)
571 {
572
573 /*
574 * WinBond/Symphony Lab 83C553 with PC87308 "SuperIO"
575 *
576 * 0.11.0 10ad.0565 PCI-ISA bridge
577 * 0.11.1 10ad.0105 IDE (slide)
578 */
579 }
580
581 void
582 motpcifix(struct brdprop *brd)
583 {
584 unsigned ide, net, pcib, steer, val;
585 int line;
586
587 pcib = pcimaketag(0, 11, 0);
588 ide = pcimaketag(0, 11, 1);
589 net = pcimaketag(0, 15, 0);
590
591 /*
592 * //// WinBond PIRQ ////
593 * 0x40 - bit 5 (0x20) indicates PIRQ presense
594 * 0x60 - PIRQ interrupt routing steer
595 */
596 if (pcicfgread(pcib, 0x40) & 0x20) {
597 steer = pcicfgread(pcib, 0x60);
598 if ((steer & 0x80808080) == 0x80808080)
599 printf("PIRQ[0-3] disabled\n");
600 else {
601 unsigned i, v = steer;
602 for (i = 0; i < 4; i++, v >>= 8) {
603 if ((v & 0x80) != 0 || (v & 0xf) == 0)
604 continue;
605 printf("PIRQ[%d]=%d\n", i, v & 0xf);
606 }
607 }
608 }
609 #if 1
610 /*
611 * //// IDE fixup -- case A ////
612 * - "native PCI mode" (ide 0x09)
613 * - don't use ISA IRQ14/15 (pcib 0x43)
614 * - native IDE for both channels (ide 0x40)
615 * - LEGIRQ bit 11 steers interrupt to pin C (ide 0x40)
616 * - sign as PCI pin C line 11 (ide 0x3d/3c)
617 */
618 /* ide: 0x09 - programming interface; 1000'SsPp */
619 val = pcicfgread(ide, 0x08);
620 val &= 0xffff00ff;
621 pcicfgwrite(ide, 0x08, val | (0x8f << 8));
622
623 /* pcib: 0x43 - IDE interrupt routing */
624 val = pcicfgread(pcib, 0x40) & 0x00ffffff;
625 pcicfgwrite(pcib, 0x40, val);
626
627 /* pcib: 0x45/44 - PCI interrupt routing */
628 val = pcicfgread(pcib, 0x44) & 0xffff0000;
629 pcicfgwrite(pcib, 0x44, val);
630
631 /* ide: 0x41/40 - IDE channel */
632 val = pcicfgread(ide, 0x40) & 0xffff0000;
633 val |= (1 << 11) | 0x33; /* LEGIRQ turns on PCI interrupt */
634 pcicfgwrite(ide, 0x40, val);
635
636 /* ide: 0x3d/3c - use PCI pin C/line 11 */
637 val = pcicfgread(ide, 0x3c) & 0xffffff00;
638 val |= 11; /* pin designation is hardwired to pin A */
639 pcicfgwrite(ide, 0x3c, val);
640 #else
641 /*
642 * //// IDE fixup -- case B ////
643 * - "compatiblity mode" (ide 0x09)
644 * - IDE primary/secondary interrupt routing (pcib 0x43)
645 * - PCI interrupt routing (pcib 0x45/44)
646 * - no PCI pin/line assignment (ide 0x3d/3c)
647 */
648 /* ide: 0x09 - programming interface; 1000'SsPp */
649 val = pcicfgread(ide, 0x08);
650 val &= 0xffff00ff;
651 pcicfgwrite(ide, 0x08, val | (0x8a << 8));
652
653 /* pcib: 0x43 - IDE interrupt routing */
654 val = pcicfgread(pcib, 0x40) & 0x00ffffff;
655 pcicfgwrite(pcib, 0x40, val | (0xee << 24));
656
657 /* ide: 0x45/44 - PCI interrupt routing */
658 val = pcicfgread(ide, 0x44) & 0xffff0000;
659 pcicfgwrite(ide, 0x44, val);
660
661 /* ide: 0x3d/3c - turn off PCI pin/line */
662 val = pcicfgread(ide, 0x3c) & 0xffff0000;
663 pcicfgwrite(ide, 0x3c, val);
664 #endif
665
666 /*
667 * //// fxp fixup ////
668 * - use PCI pin A line 15 (fxp 0x3d/3c)
669 */
670 val = pcicfgread(net, 0x3c) & 0xffff0000;
671 pcidecomposetag(net, NULL, &line, NULL);
672 val |= (('A' - '@') << 8) | line;
673 pcicfgwrite(net, 0x3c, val);
674 }
675
676 void
677 kurosetup(struct brdprop *brd)
678 {
679
680 if (PCI_VENDOR(pcicfgread(pcimaketag(0, 11, 0), PCI_ID_REG)) == 0x10ec)
681 brd->extclk = 32768000; /* decr 2457600Hz */
682 else
683 brd->extclk = 32521333; /* decr 2439100Hz */
684 }
685
686 void
687 kurobrdfix(struct brdprop *brd)
688 {
689
690 init_uart(uart2base, 9600, LCR_8BITS | LCR_PEVEN);
691 /* Stop Watchdog */
692 send_sat("AAAAFFFFJJJJ>>>>VVVV>>>>ZZZZVVVVKKKK");
693 }
694
695 void
696 kuroreset()
697 {
698
699 send_sat("CCGG");
700 /*NOTREACHED*/
701 }
702
703 void
704 synosetup(struct brdprop *brd)
705 {
706
707 if (1) /* 200 and 266MHz models */
708 brd->extclk = 33164691; /* from Synology/Linux source */
709 else /* 400MHz models XXX how to check? */
710 brd->extclk = 33165343;
711 }
712
713 void
714 synobrdfix(struct brdprop *brd)
715 {
716
717 init_uart(uart2base, 9600, LCR_8BITS | LCR_PNONE);
718 /* beep, power LED on, status LED off */
719 send_sat("247");
720 }
721
722 void
723 synopcifix(struct brdprop *brd)
724 {
725 static const char csmodel[4][7] = {
726 "CS406e", "CS406", "RS406", "CS407e"
727 };
728 volatile uint8_t *cpld = (volatile uint8_t *)0xff000000;
729 uint8_t pwrstate;
730
731 if (nata > 1) {
732 /*
733 * CS/RS stations power-up their disks one after another.
734 * We have to watch over the current power state in a CPLD
735 * register, until all disks become available.
736 */
737 printf("CPLD V1.%d for model %s\n", cpld[2] & 3,
738 csmodel[(cpld[2] & 0x0c) >> 2]);
739 cpld[0] = 0x00; /* all drive LEDs blinking yellow */
740 do {
741 delay(1000 * 1000);
742 pwrstate = cpld[1];
743 printf("Power state: %02x\r", pwrstate);
744 } while (pwrstate != 0xff);
745 putchar('\n');
746 }
747 }
748
749 void
750 synolaunch(struct brdprop *brd)
751 {
752 volatile uint8_t *cpld = (volatile uint8_t *)0xff000000;
753 struct dkdev_ata *sata1, *sata2;
754
755 if (nata > 1) {
756 /* enable drive LEDs for active disk drives on CS/RS models */
757 sata1 = lata[0].drv;
758 sata2 = lata[1].drv;
759 cpld[0] = (sata1->presense[0] ? 0x80 : 0xc0) |
760 (sata1->presense[1] ? 0x20 : 0x30) |
761 (sata2->presense[0] ? 0x08 : 0x0c) |
762 (sata2->presense[1] ? 0x02 : 0x03);
763 }
764 }
765
766 void
767 synoreset()
768 {
769
770 send_sat("C");
771 /*NOTREACHED*/
772 }
773
774 void
775 qnapbrdfix(struct brdprop *brd)
776 {
777
778 init_uart(uart2base, 19200, LCR_8BITS | LCR_PNONE);
779 /* beep, status LED red */
780 send_sat("PW");
781 }
782
783 void
784 qnapreset()
785 {
786
787 send_sat("f");
788 /*NOTREACHED*/
789 }
790
791 void
792 iomegabrdfix(struct brdprop *brd)
793 {
794
795 init_uart(uart2base, 9600, LCR_8BITS | LCR_PNONE);
796 /* LED flashing blue, fan auto, turn on at 50C, turn off at 45C */
797 send_iomega('b', 'd', 2, 'a', 50, 45);
798 }
799
800 void
801 iomegareset()
802 {
803
804 send_iomega('g', 0, 0, 0, 0, 0);
805 /*NOTREACHED*/
806 }
807
808 void
809 dlinkbrdfix(struct brdprop *brd)
810 {
811
812 init_uart(uart2base, 9600, LCR_8BITS | LCR_PNONE);
813 send_sat("SYN\n");
814 send_sat("ZWO\n"); /* power LED solid on */
815 }
816
817 void
818 nhnasbrdfix(struct brdprop *brd)
819 {
820
821 /* status LED off, USB-LEDs on, low-speed fan */
822 NHGPIO_WRITE(0x04);
823 }
824
825 void
826 nhnasreset()
827 {
828
829 /* status LED on, assert system-reset to all devices */
830 NHGPIO_WRITE(0x02);
831 delay(100000);
832 /*NOTREACHED*/
833 }
834
835 void
836 kurot4brdfix(struct brdprop *brd)
837 {
838
839 init_uart(uart2base, 38400, LCR_8BITS | LCR_PEVEN);
840 }
841
842 void
843 _rtt(void)
844 {
845 uint32_t msr;
846
847 netif_shutdown_all();
848
849 if (brdprop->reset != NULL)
850 (*brdprop->reset)();
851 else {
852 msr = mfmsr();
853 msr &= ~PSL_EE;
854 mtmsr(msr);
855 asm volatile ("sync; isync");
856 asm volatile("mtspr %0,%1" : : "K"(81), "r"(0));
857 msr &= ~(PSL_ME | PSL_DR | PSL_IR);
858 mtmsr(msr);
859 asm volatile ("sync; isync");
860 run(0, 0, 0, 0, (void *)0xFFF00100); /* reset entry */
861 }
862 __unreachable();
863 }
864
865 satime_t
866 getsecs(void)
867 {
868 u_quad_t tb = mftb();
869
870 return (tb / ticks_per_sec);
871 }
872
873 /*
874 * Wait for about n microseconds (at least!).
875 */
876 void
877 delay(u_int n)
878 {
879 u_quad_t tb;
880 u_long scratch, tbh, tbl;
881
882 tb = mftb();
883 tb += (n * 1000 + ns_per_tick - 1) / ns_per_tick;
884 tbh = tb >> 32;
885 tbl = tb;
886 asm volatile ("1: mftbu %0; cmpw %0,%1; blt 1b; bgt 2f; mftb %0; cmpw 0, %0,%2; blt 1b; 2:" : "=&r"(scratch) : "r"(tbh), "r"(tbl));
887 }
888
889 void
890 _wb(uint32_t adr, uint32_t siz)
891 {
892 uint32_t bnd;
893
894 asm volatile("eieio");
895 for (bnd = adr + siz; adr < bnd; adr += dcache_line_size)
896 asm volatile ("dcbst 0,%0" :: "r"(adr));
897 asm volatile ("sync");
898 }
899
900 void
901 _wbinv(uint32_t adr, uint32_t siz)
902 {
903 uint32_t bnd;
904
905 asm volatile("eieio");
906 for (bnd = adr + siz; adr < bnd; adr += dcache_line_size)
907 asm volatile ("dcbf 0,%0" :: "r"(adr));
908 asm volatile ("sync");
909 }
910
911 void
912 _inv(uint32_t adr, uint32_t siz)
913 {
914 uint32_t bnd, off;
915
916 off = adr & (dcache_line_size - 1);
917 adr -= off;
918 siz += off;
919 asm volatile ("eieio");
920 if (off != 0) {
921 /* wbinv() leading unaligned dcache line */
922 asm volatile ("dcbf 0,%0" :: "r"(adr));
923 if (siz < dcache_line_size)
924 goto done;
925 adr += dcache_line_size;
926 siz -= dcache_line_size;
927 }
928 bnd = adr + siz;
929 off = bnd & (dcache_line_size - 1);
930 if (off != 0) {
931 /* wbinv() trailing unaligned dcache line */
932 asm volatile ("dcbf 0,%0" :: "r"(bnd)); /* it's OK */
933 if (siz < dcache_line_size)
934 goto done;
935 siz -= off;
936 }
937 for (bnd = adr + siz; adr < bnd; adr += dcache_line_size) {
938 /* inv() intermediate dcache lines if ever */
939 asm volatile ("dcbi 0,%0" :: "r"(adr));
940 }
941 done:
942 asm volatile ("sync");
943 }
944
945 static inline uint32_t
946 mfmsr(void)
947 {
948 uint32_t msr;
949
950 asm volatile ("mfmsr %0" : "=r"(msr));
951 return msr;
952 }
953
954 static inline void
955 mtmsr(uint32_t msr)
956 {
957 asm volatile ("mtmsr %0" : : "r"(msr));
958 }
959
960 static inline uint32_t
961 cputype(void)
962 {
963 uint32_t pvr;
964
965 asm volatile ("mfpvr %0" : "=r"(pvr));
966 return pvr >> 16;
967 }
968
969 static inline u_quad_t
970 mftb(void)
971 {
972 u_long scratch;
973 u_quad_t tb;
974
975 asm ("1: mftbu %0; mftb %0+1; mftbu %1; cmpw %0,%1; bne 1b"
976 : "=r"(tb), "=r"(scratch));
977 return tb;
978 }
979
980 static void
981 init_uart(unsigned base, unsigned speed, uint8_t lcr)
982 {
983 unsigned div;
984
985 div = busclock / speed / 16;
986 UART_WRITE(base, LCR, 0x80); /* turn on DLAB bit */
987 UART_WRITE(base, FCR, 0x00);
988 UART_WRITE(base, DMB, div >> 8); /* set speed */
989 UART_WRITE(base, DLB, div & 0xff);
990 UART_WRITE(base, LCR, lcr);
991 UART_WRITE(base, FCR, 0x07); /* FIFO on, TXRX FIFO reset */
992 UART_WRITE(base, IER, 0x00); /* make sure INT disabled */
993 }
994
995 /* talk to satellite processor */
996 static void
997 send_sat(char *msg)
998 {
999 unsigned savedbase;
1000
1001 savedbase = uart1base;
1002 uart1base = uart2base;
1003 while (*msg)
1004 putchar(*msg++);
1005 uart1base = savedbase;
1006 }
1007
1008 #ifdef DEBUG
1009 static void
1010 iomega_debug(const char *txt, uint8_t buf[])
1011 {
1012 int i;
1013
1014 printf("%s:", txt);
1015 for (i = 0; i < IOMEGA_PACKETSIZE; i++)
1016 printf(" %02x", buf[i]);
1017 putchar('\n');
1018 }
1019 #endif /* DEBUG */
1020
1021 static void
1022 send_iomega(int power, int led, int rate, int fan, int high, int low)
1023 {
1024 uint8_t buf[IOMEGA_PACKETSIZE];
1025 unsigned i, savedbase;
1026
1027 savedbase = uart1base;
1028 uart1base = uart2base;
1029
1030 /* first flush the receive buffer */
1031 again:
1032 while (tstchar())
1033 (void)getchar();
1034 delay(20000);
1035 if (tstchar())
1036 goto again;
1037 /*
1038 * Now synchronize the transmitter by sending 0x00
1039 * until we receive a status reply.
1040 */
1041 do {
1042 putchar(0);
1043 delay(50000);
1044 } while (!tstchar());
1045
1046 for (i = 0; i < IOMEGA_PACKETSIZE; i++)
1047 buf[i] = getchar();
1048 #ifdef DEBUG
1049 uart1base = savedbase;
1050 iomega_debug("68HC908 status", buf);
1051 uart1base = uart2base;
1052 #endif
1053
1054 /* send command */
1055 buf[IOMEGA_POWER] = power;
1056 buf[IOMEGA_LED] = led;
1057 buf[IOMEGA_FLASH_RATE] = rate;
1058 buf[IOMEGA_FAN] = fan;
1059 buf[IOMEGA_HIGH_TEMP] = high;
1060 buf[IOMEGA_LOW_TEMP] = low;
1061 buf[IOMEGA_ID] = 7; /* host id */
1062 buf[IOMEGA_CHECKSUM] = (buf[IOMEGA_POWER] + buf[IOMEGA_LED] +
1063 buf[IOMEGA_FLASH_RATE] + buf[IOMEGA_FAN] +
1064 buf[IOMEGA_HIGH_TEMP] + buf[IOMEGA_LOW_TEMP] +
1065 buf[IOMEGA_ID]) & 0x7f;
1066 #ifdef DEBUG
1067 uart1base = savedbase;
1068 iomega_debug("G2 sending", buf);
1069 uart1base = uart2base;
1070 #endif
1071 for (i = 0; i < IOMEGA_PACKETSIZE; i++)
1072 putchar(buf[i]);
1073
1074 /* receive the reply */
1075 for (i = 0; i < IOMEGA_PACKETSIZE; i++)
1076 buf[i] = getchar();
1077 #ifdef DEBUG
1078 uart1base = savedbase;
1079 iomega_debug("68HC908 reply", buf);
1080 uart1base = uart2base;
1081 #endif
1082
1083 if (buf[0] == '#')
1084 goto again; /* try again on error */
1085 uart1base = savedbase;
1086 }
1087
1088 void
1089 putchar(int c)
1090 {
1091 unsigned timo, lsr;
1092
1093 if (c == '\n')
1094 putchar('\r');
1095
1096 timo = 0x00100000;
1097 do {
1098 lsr = UART_READ(uart1base, LSR);
1099 } while (timo-- > 0 && (lsr & LSR_THRE) == 0);
1100 if (timo > 0)
1101 UART_WRITE(uart1base, THR, c);
1102 }
1103
1104 int
1105 getchar(void)
1106 {
1107 unsigned lsr;
1108
1109 do {
1110 lsr = UART_READ(uart1base, LSR);
1111 } while ((lsr & LSR_DRDY) == 0);
1112 return UART_READ(uart1base, RBR);
1113 }
1114
1115 int
1116 tstchar(void)
1117 {
1118
1119 return (UART_READ(uart1base, LSR) & LSR_DRDY) != 0;
1120 }
1121
1122 #define SAR_MASK 0x0ff00000
1123 #define SAR_SHIFT 20
1124 #define EAR_MASK 0x30000000
1125 #define EAR_SHIFT 28
1126 #define AR(v, s) ((((v) & SAR_MASK) >> SAR_SHIFT) << (s))
1127 #define XR(v, s) ((((v) & EAR_MASK) >> EAR_SHIFT) << (s))
1128 static void
1129 set_mem_bounds(unsigned tag, unsigned bk_en, ...)
1130 {
1131 unsigned mbst, mbxst, mben, mbxen;
1132 unsigned start, end;
1133 va_list ap;
1134 int i, sh;
1135
1136 va_start(ap, bk_en);
1137 mbst = mbxst = mben = mbxen = 0;
1138
1139 for (i = 0; i < 4; i++) {
1140 if ((bk_en & (1U << i)) != 0) {
1141 start = va_arg(ap, unsigned);
1142 end = va_arg(ap, unsigned);
1143 } else {
1144 start = 0x3ff00000;
1145 end = 0x3fffffff;
1146 }
1147 sh = i << 3;
1148 mbst |= AR(start, sh);
1149 mbxst |= XR(start, sh);
1150 mben |= AR(end, sh);
1151 mbxen |= XR(end, sh);
1152 }
1153 va_end(ap);
1154
1155 pcicfgwrite(tag, MPC106_MEMSTARTADDR1, mbst);
1156 pcicfgwrite(tag, MPC106_EXTMEMSTARTADDR1, mbxst);
1157 pcicfgwrite(tag, MPC106_MEMENDADDR1, mben);
1158 pcicfgwrite(tag, MPC106_EXTMEMENDADDR1, mbxen);
1159 pcicfgwrite(tag, MPC106_MEMEN,
1160 (pcicfgread(tag, MPC106_MEMEN) & ~0xff) | (bk_en & 0xff));
1161 }
1162
1163 static unsigned
1164 mpc107memsize(void)
1165 {
1166 unsigned bankn, end, n, tag, val;
1167
1168 tag = pcimaketag(0, 0, 0);
1169
1170 if (brdtype == BRD_ENCOREPP1) {
1171 /* the brd's PPCBOOT looks to have erroneous values */
1172 set_mem_bounds(tag, 1, 0x00000000, (128 << 20) - 1);
1173 } else if (brdtype == BRD_NH230NAS) {
1174 /*
1175 * PPCBoot sets the end address to 0x7ffffff, although the
1176 * board has just 64MB (0x3ffffff).
1177 */
1178 set_mem_bounds(tag, 1, 0x00000000, 0x03ffffff);
1179 }
1180
1181 bankn = 0;
1182 val = pcicfgread(tag, MPC106_MEMEN);
1183 for (n = 0; n < 4; n++) {
1184 if ((val & (1U << n)) == 0)
1185 break;
1186 bankn = n;
1187 }
1188 bankn <<= 3;
1189
1190 val = pcicfgread(tag, MPC106_EXTMEMENDADDR1);
1191 end = ((val >> bankn) & 0x03) << 28;
1192 val = pcicfgread(tag, MPC106_MEMENDADDR1);
1193 end |= ((val >> bankn) & 0xff) << 20;
1194 end |= 0xfffff;
1195
1196 return (end + 1); /* assume the end address matches total amount */
1197 }
1198
1199 struct fis_dir_entry {
1200 char name[16];
1201 uint32_t startaddr;
1202 uint32_t loadaddr;
1203 uint32_t flashsize;
1204 uint32_t entryaddr;
1205 uint32_t filesize;
1206 char pad[256 - (16 + 5 * sizeof(uint32_t))];
1207 };
1208
1209 #define FIS_LOWER_LIMIT 0xfff00000
1210
1211 /*
1212 * Look for a Redboot-style Flash Image System FIS-directory and
1213 * return a pointer to the start address of the requested file.
1214 */
1215 static void *
1216 redboot_fis_lookup(const char *filename)
1217 {
1218 static const char FISdirname[16] = {
1219 'F', 'I', 'S', ' ',
1220 'd', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 0, 0, 0
1221 };
1222 struct fis_dir_entry *dir;
1223
1224 /*
1225 * The FIS directory is usually in the last sector of the flash.
1226 * But we do not know the sector size (erase size), so start
1227 * at 0xffffff00 and scan backwards in steps of the FIS directory
1228 * entry size (0x100).
1229 */
1230 for (dir = (struct fis_dir_entry *)0xffffff00;
1231 (uint32_t)dir >= FIS_LOWER_LIMIT; dir--)
1232 if (memcmp(dir->name, FISdirname, sizeof(FISdirname)) == 0)
1233 break;
1234 if ((uint32_t)dir < FIS_LOWER_LIMIT) {
1235 printf("No FIS directory found!\n");
1236 return NULL;
1237 }
1238
1239 /* Now find filename by scanning the directory from beginning. */
1240 dir = (struct fis_dir_entry *)dir->startaddr;
1241 while (dir->name[0] != 0xff && (uint32_t)dir < 0xffffff00) {
1242 if (strcmp(dir->name, filename) == 0)
1243 return (void *)dir->startaddr; /* found */
1244 dir++;
1245 }
1246 printf("\"%s\" not found in FIS directory!\n", filename);
1247 return NULL;
1248 }
1249
1250 static void
1251 read_mac_string(uint8_t *mac, char *p)
1252 {
1253 int i;
1254
1255 for (i = 0; i < 6; i++, p += 3)
1256 *mac++ = read_hex(p);
1257 }
1258
1259 /*
1260 * Scan through the Flash memory and look for a string starting at 512 bytes
1261 * block boundaries, matching the format: xx:xx:xx:xx:xx:xx<NUL>, where "x"
1262 * are hexadecimal digits.
1263 * Read the first match as our MAC address.
1264 * The start address of the search, p, *must* be dividable by 512!
1265 * Return false when no suitable MAC string was found.
1266 */
1267 static int
1268 find_mac_string(uint8_t *mac, char *p)
1269 {
1270 int i;
1271
1272 for (;;) {
1273 for (i = 0; i < 3 * 6; i += 3) {
1274 if (!isxdigit((unsigned)p[i]) ||
1275 !isxdigit((unsigned)p[i + 1]))
1276 break;
1277 if ((i < 5 && p[i + 2] != ':') ||
1278 (i >= 5 && p[i + 2] != '\0'))
1279 break;
1280 }
1281 if (i >= 6) {
1282 /* found a valid MAC address */
1283 read_mac_string(mac, p);
1284 return 1;
1285 }
1286 if (p >= (char *)0xfffffe00)
1287 break;
1288 p += 0x200;
1289 }
1290 return 0;
1291 }
1292
1293
1294 /*
1295 * For cost saving reasons some NAS boxes lack SEEPROM for NIC's
1296 * ethernet address and keep it in their Flash memory instead.
1297 */
1298 void
1299 read_mac_from_flash(uint8_t *mac)
1300 {
1301 uint8_t *p;
1302
1303 switch (brdtype) {
1304 case BRD_SYNOLOGY:
1305 p = redboot_fis_lookup("vendor");
1306 if (p == NULL)
1307 break;
1308 memcpy(mac, p, 6);
1309 return;
1310 case BRD_DLINKDSM:
1311 read_mac_string(mac, (char *)0xfff0ff80);
1312 return;
1313 case BRD_QNAPTS:
1314 if (find_mac_string(mac, (char *)0xfff00000))
1315 return;
1316 break;
1317 default:
1318 printf("Warning: This board has no known method defined "
1319 "to determine its MAC address!\n");
1320 break;
1321 }
1322
1323 /* set to 00:00:00:00:00:00 in case of error */
1324 memset(mac, 0, 6);
1325 }
1326
1327 #ifdef DEBUG
1328 void
1329 sat_write(char *p, int len)
1330 {
1331 unsigned savedbase;
1332
1333 savedbase = uart1base;
1334 uart1base = uart2base;
1335 while (len--)
1336 putchar(*p++);
1337 uart1base = savedbase;
1338 }
1339
1340 int
1341 sat_getch(void)
1342 {
1343 unsigned lsr;
1344
1345 do {
1346 lsr = UART_READ(uart2base, LSR);
1347 } while ((lsr & LSR_DRDY) == 0);
1348 return UART_READ(uart2base, RBR);
1349 }
1350
1351 int
1352 sat_tstch(void)
1353 {
1354
1355 return (UART_READ(uart2base, LSR) & LSR_DRDY) != 0;
1356 }
1357 #endif /* DEBUG */
1358