brdsetup.c revision 1.5.2.2 1 1.5.2.2 rmind /* $NetBSD: brdsetup.c,v 1.5.2.2 2011/03/05 20:51:47 rmind Exp $ */
2 1.5.2.2 rmind
3 1.5.2.2 rmind /*-
4 1.5.2.2 rmind * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 1.5.2.2 rmind * All rights reserved.
6 1.5.2.2 rmind *
7 1.5.2.2 rmind * This code is derived from software contributed to The NetBSD Foundation
8 1.5.2.2 rmind * by Tohru Nishimura.
9 1.5.2.2 rmind *
10 1.5.2.2 rmind * Redistribution and use in source and binary forms, with or without
11 1.5.2.2 rmind * modification, are permitted provided that the following conditions
12 1.5.2.2 rmind * are met:
13 1.5.2.2 rmind * 1. Redistributions of source code must retain the above copyright
14 1.5.2.2 rmind * notice, this list of conditions and the following disclaimer.
15 1.5.2.2 rmind * 2. Redistributions in binary form must reproduce the above copyright
16 1.5.2.2 rmind * notice, this list of conditions and the following disclaimer in the
17 1.5.2.2 rmind * documentation and/or other materials provided with the distribution.
18 1.5.2.2 rmind *
19 1.5.2.2 rmind * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.5.2.2 rmind * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.5.2.2 rmind * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.5.2.2 rmind * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.5.2.2 rmind * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.5.2.2 rmind * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.5.2.2 rmind * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.5.2.2 rmind * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.5.2.2 rmind * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.5.2.2 rmind * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.5.2.2 rmind * POSSIBILITY OF SUCH DAMAGE.
30 1.5.2.2 rmind */
31 1.5.2.2 rmind
32 1.5.2.2 rmind #include <sys/param.h>
33 1.5.2.2 rmind
34 1.5.2.2 rmind #include <powerpc/oea/spr.h>
35 1.5.2.2 rmind
36 1.5.2.2 rmind #include <lib/libsa/stand.h>
37 1.5.2.2 rmind #include <lib/libsa/net.h>
38 1.5.2.2 rmind #include <lib/libkern/libkern.h>
39 1.5.2.2 rmind
40 1.5.2.2 rmind #include <machine/bootinfo.h>
41 1.5.2.2 rmind
42 1.5.2.2 rmind #include "globals.h"
43 1.5.2.2 rmind
44 1.5.2.2 rmind #define BRD_DECL(xxx) \
45 1.5.2.2 rmind void xxx ## setup(struct brdprop *); \
46 1.5.2.2 rmind void xxx ## brdfix(struct brdprop *); \
47 1.5.2.2 rmind void xxx ## pcifix(struct brdprop *); \
48 1.5.2.2 rmind void xxx ## reset(void)
49 1.5.2.2 rmind
50 1.5.2.2 rmind BRD_DECL(mot);
51 1.5.2.2 rmind BRD_DECL(enc);
52 1.5.2.2 rmind BRD_DECL(kuro);
53 1.5.2.2 rmind BRD_DECL(syno);
54 1.5.2.2 rmind BRD_DECL(qnap);
55 1.5.2.2 rmind BRD_DECL(iomega);
56 1.5.2.2 rmind BRD_DECL(dlink);
57 1.5.2.2 rmind BRD_DECL(nhnas);
58 1.5.2.2 rmind
59 1.5.2.2 rmind static struct brdprop brdlist[] = {
60 1.5.2.2 rmind {
61 1.5.2.2 rmind "sandpoint",
62 1.5.2.2 rmind "Sandpoint X3",
63 1.5.2.2 rmind BRD_SANDPOINTX3,
64 1.5.2.2 rmind 0,
65 1.5.2.2 rmind "com", 0x3f8, 115200,
66 1.5.2.2 rmind motsetup, motbrdfix, motpcifix, NULL },
67 1.5.2.2 rmind {
68 1.5.2.2 rmind "encpp1",
69 1.5.2.2 rmind "EnCore PP1",
70 1.5.2.2 rmind BRD_ENCOREPP1,
71 1.5.2.2 rmind 0,
72 1.5.2.2 rmind "com", 0x3f8, 115200,
73 1.5.2.2 rmind encsetup, encbrdfix, encpcifix, NULL },
74 1.5.2.2 rmind {
75 1.5.2.2 rmind "kurobox",
76 1.5.2.2 rmind "KuroBox",
77 1.5.2.2 rmind BRD_KUROBOX,
78 1.5.2.2 rmind 32768000,
79 1.5.2.2 rmind "eumb", 0x4600, 57600,
80 1.5.2.2 rmind kurosetup, kurobrdfix, NULL, NULL },
81 1.5.2.2 rmind {
82 1.5.2.2 rmind "synology",
83 1.5.2.2 rmind "Synology DS",
84 1.5.2.2 rmind BRD_SYNOLOGY,
85 1.5.2.2 rmind 33164691, /* from Synology/Linux source */
86 1.5.2.2 rmind /* 33168000, XXX better precision? */
87 1.5.2.2 rmind "eumb", 0x4500, 115200,
88 1.5.2.2 rmind NULL, synobrdfix, NULL, synoreset },
89 1.5.2.2 rmind {
90 1.5.2.2 rmind "qnap",
91 1.5.2.2 rmind "QNAP TS-101",
92 1.5.2.2 rmind BRD_QNAPTS101,
93 1.5.2.2 rmind 0,
94 1.5.2.2 rmind "eumb", 0x4500, 115200,
95 1.5.2.2 rmind NULL, qnapbrdfix, NULL, NULL },
96 1.5.2.2 rmind {
97 1.5.2.2 rmind "iomega",
98 1.5.2.2 rmind "IOMEGA StorCenter",
99 1.5.2.2 rmind BRD_STORCENTER,
100 1.5.2.2 rmind 0,
101 1.5.2.2 rmind "eumb", 0x4500, 115200,
102 1.5.2.2 rmind NULL, iomegabrdfix, NULL, NULL },
103 1.5.2.2 rmind {
104 1.5.2.2 rmind "dlink",
105 1.5.2.2 rmind "D-Link DSM-G600",
106 1.5.2.2 rmind BRD_DLINKDSM,
107 1.5.2.2 rmind 0,
108 1.5.2.2 rmind "eumb", 0x4500, 9600,
109 1.5.2.2 rmind NULL, dlinkbrdfix, NULL, NULL },
110 1.5.2.2 rmind {
111 1.5.2.2 rmind "nhnas",
112 1.5.2.2 rmind "Netronics NH230/231",
113 1.5.2.2 rmind BRD_NH230NAS,
114 1.5.2.2 rmind 0,
115 1.5.2.2 rmind "eumb", 0x4500, 9600,
116 1.5.2.2 rmind NULL, nhnasbrdfix, NULL, NULL },
117 1.5.2.2 rmind {
118 1.5.2.2 rmind "unknown",
119 1.5.2.2 rmind "Unknown board",
120 1.5.2.2 rmind BRD_UNKNOWN,
121 1.5.2.2 rmind 0,
122 1.5.2.2 rmind "eumb", 0x4500, 115200,
123 1.5.2.2 rmind NULL, NULL, NULL, NULL }, /* must be the last */
124 1.5.2.2 rmind };
125 1.5.2.2 rmind
126 1.5.2.2 rmind static struct brdprop *brdprop;
127 1.5.2.2 rmind static uint32_t ticks_per_sec, ns_per_tick;
128 1.5.2.2 rmind
129 1.5.2.2 rmind static void brdfixup(void);
130 1.5.2.2 rmind static void setup(void);
131 1.5.2.2 rmind static inline uint32_t cputype(void);
132 1.5.2.2 rmind static inline u_quad_t mftb(void);
133 1.5.2.2 rmind static void init_uart(unsigned, unsigned, uint8_t);
134 1.5.2.2 rmind static void send_sat(char *);
135 1.5.2.2 rmind
136 1.5.2.2 rmind const unsigned dcache_line_size = 32; /* 32B linesize */
137 1.5.2.2 rmind const unsigned dcache_range_size = 4 * 1024; /* 16KB / 4-way */
138 1.5.2.2 rmind
139 1.5.2.2 rmind unsigned uart1base; /* console */
140 1.5.2.2 rmind unsigned uart2base; /* optional satellite processor */
141 1.5.2.2 rmind #define THR 0
142 1.5.2.2 rmind #define DLB 0
143 1.5.2.2 rmind #define DMB 1
144 1.5.2.2 rmind #define IER 1
145 1.5.2.2 rmind #define FCR 2
146 1.5.2.2 rmind #define LCR 3
147 1.5.2.2 rmind #define LCR_DLAB 0x80
148 1.5.2.2 rmind #define LCR_PEVEN 0x18
149 1.5.2.2 rmind #define LCR_PNONE 0x00
150 1.5.2.2 rmind #define LCR_8BITS 0x03
151 1.5.2.2 rmind #define MCR 4
152 1.5.2.2 rmind #define MCR_RTS 0x02
153 1.5.2.2 rmind #define MCR_DTR 0x01
154 1.5.2.2 rmind #define LSR 5
155 1.5.2.2 rmind #define LSR_THRE 0x20
156 1.5.2.2 rmind #define DCR 0x11
157 1.5.2.2 rmind #define UART_READ(base, r) *(volatile char *)(base + (r))
158 1.5.2.2 rmind #define UART_WRITE(base, r, v) *(volatile char *)(base + (r)) = (v)
159 1.5.2.2 rmind
160 1.5.2.2 rmind void brdsetup(void); /* called by entry.S */
161 1.5.2.2 rmind
162 1.5.2.2 rmind void
163 1.5.2.2 rmind brdsetup(void)
164 1.5.2.2 rmind {
165 1.5.2.2 rmind static uint8_t pci_to_memclk[] = {
166 1.5.2.2 rmind 30, 30, 10, 10, 20, 10, 10, 10,
167 1.5.2.2 rmind 10, 20, 20, 15, 20, 15, 20, 30,
168 1.5.2.2 rmind 30, 40, 15, 40, 20, 25, 20, 40,
169 1.5.2.2 rmind 25, 20, 10, 20, 15, 15, 20, 00
170 1.5.2.2 rmind };
171 1.5.2.2 rmind static uint8_t mem_to_cpuclk[] = {
172 1.5.2.2 rmind 25, 30, 45, 20, 20, 00, 10, 30,
173 1.5.2.2 rmind 30, 20, 45, 30, 25, 35, 30, 35,
174 1.5.2.2 rmind 20, 25, 20, 30, 35, 40, 40, 20,
175 1.5.2.2 rmind 30, 25, 40, 30, 30, 25, 35, 00
176 1.5.2.2 rmind };
177 1.5.2.2 rmind char *consname;
178 1.5.2.2 rmind int consport;
179 1.5.2.2 rmind uint32_t extclk;
180 1.5.2.2 rmind unsigned pchb, pcib, dev11, dev13, dev15, dev16, val;
181 1.5.2.2 rmind extern struct btinfo_memory bi_mem;
182 1.5.2.2 rmind extern struct btinfo_console bi_cons;
183 1.5.2.2 rmind extern struct btinfo_clock bi_clk;
184 1.5.2.2 rmind extern struct btinfo_prodfamily bi_fam;
185 1.5.2.2 rmind
186 1.5.2.2 rmind /*
187 1.5.2.2 rmind * CHRP specification "Map-B" BAT012 layout
188 1.5.2.2 rmind * BAT0 0000-0000 (256MB) SDRAM
189 1.5.2.2 rmind * BAT1 8000-0000 (256MB) PCI mem space
190 1.5.2.2 rmind * BAT2 fc00-0000 (64MB) EUMB, PCI I/O space, misc devs, flash
191 1.5.2.2 rmind *
192 1.5.2.2 rmind * EUMBBAR is at fc00-0000.
193 1.5.2.2 rmind */
194 1.5.2.2 rmind pchb = pcimaketag(0, 0, 0);
195 1.5.2.2 rmind pcicfgwrite(pchb, 0x78, 0xfc000000);
196 1.5.2.2 rmind
197 1.5.2.2 rmind brdtype = BRD_UNKNOWN;
198 1.5.2.2 rmind extclk = EXT_CLK_FREQ; /* usually 33MHz */
199 1.5.2.2 rmind busclock = 0;
200 1.5.2.2 rmind
201 1.5.2.2 rmind dev11 = pcimaketag(0, 11, 0);
202 1.5.2.2 rmind dev13 = pcimaketag(0, 13, 0);
203 1.5.2.2 rmind dev15 = pcimaketag(0, 15, 0);
204 1.5.2.2 rmind dev16 = pcimaketag(0, 16, 0);
205 1.5.2.2 rmind
206 1.5.2.2 rmind if (pcifinddev(0x10ad, 0x0565, &pcib) == 0) {
207 1.5.2.2 rmind /* WinBond 553 southbridge at dev 11 */
208 1.5.2.2 rmind brdtype = BRD_SANDPOINTX3;
209 1.5.2.2 rmind }
210 1.5.2.2 rmind else if (pcifinddev(0x1106, 0x0686, &pcib) == 0) {
211 1.5.2.2 rmind /* VIA 686B southbridge at dev 22 */
212 1.5.2.2 rmind brdtype = BRD_ENCOREPP1;
213 1.5.2.2 rmind }
214 1.5.2.2 rmind else if ((pcicfgread(dev11, PCI_CLASS_REG) >> 16) == PCI_CLASS_ETH) {
215 1.5.2.2 rmind /* ADMtek AN985 (tlp) or RealTek 8169S (re) at dev 11 */
216 1.5.2.2 rmind brdtype = BRD_KUROBOX;
217 1.5.2.2 rmind }
218 1.5.2.2 rmind else if (PCI_VENDOR(pcicfgread(dev15, PCI_ID_REG)) == 0x11ab) {
219 1.5.2.2 rmind /* SKnet/Marvell (sk) at dev 15 */
220 1.5.2.2 rmind brdtype = BRD_SYNOLOGY;
221 1.5.2.2 rmind }
222 1.5.2.2 rmind else if (PCI_VENDOR(pcicfgread(dev15, PCI_ID_REG)) == 0x8086) {
223 1.5.2.2 rmind /* Intel (wm) at dev 15 */
224 1.5.2.2 rmind brdtype = BRD_QNAPTS101;
225 1.5.2.2 rmind }
226 1.5.2.2 rmind else if (PCI_VENDOR(pcicfgread(dev13, PCI_ID_REG)) == 0x1106) {
227 1.5.2.2 rmind /* VIA 6410 (viaide) at dev 13 */
228 1.5.2.2 rmind brdtype = BRD_STORCENTER;
229 1.5.2.2 rmind }
230 1.5.2.2 rmind else if (PCI_VENDOR(pcicfgread(dev16, PCI_ID_REG)) == 0x1191) {
231 1.5.2.2 rmind /* ACARD ATP865 (acardide) at dev 16 */
232 1.5.2.2 rmind brdtype = BRD_DLINKDSM;
233 1.5.2.2 rmind }
234 1.5.2.2 rmind else if (PCI_VENDOR(pcicfgread(dev16, PCI_ID_REG)) == 0x1283
235 1.5.2.2 rmind || PCI_VENDOR(pcicfgread(dev16, PCI_ID_REG)) == 0x1095) {
236 1.5.2.2 rmind /* ITE (iteide) or SiI (satalink) at dev 16 */
237 1.5.2.2 rmind brdtype = BRD_NH230NAS;
238 1.5.2.2 rmind }
239 1.5.2.2 rmind
240 1.5.2.2 rmind brdprop = brd_lookup(brdtype);
241 1.5.2.2 rmind
242 1.5.2.2 rmind /* brd dependent adjustments */
243 1.5.2.2 rmind setup();
244 1.5.2.2 rmind
245 1.5.2.2 rmind /* determine clock frequencies */
246 1.5.2.2 rmind if (brdprop->extclk != 0)
247 1.5.2.2 rmind extclk = brdprop->extclk;
248 1.5.2.2 rmind if (busclock == 0) {
249 1.5.2.2 rmind if (cputype() == MPC8245) {
250 1.5.2.2 rmind /* PLL_CFG from PCI host bridge register 0xe2 */
251 1.5.2.2 rmind val = pcicfgread(pchb, 0xe0);
252 1.5.2.2 rmind busclock = (extclk *
253 1.5.2.2 rmind pci_to_memclk[(val >> 19) & 0x1f] + 10) / 10;
254 1.5.2.2 rmind /* PLLRATIO from HID1 */
255 1.5.2.2 rmind __asm ("mfspr %0,1009" : "=r"(val));
256 1.5.2.2 rmind cpuclock = ((uint64_t)busclock *
257 1.5.2.2 rmind mem_to_cpuclk[val >> 27] + 10) / 10;
258 1.5.2.2 rmind } else
259 1.5.2.2 rmind busclock = 100000000; /* 100MHz bus clock default */
260 1.5.2.2 rmind }
261 1.5.2.2 rmind ticks_per_sec = busclock >> 2;
262 1.5.2.2 rmind ns_per_tick = 1000000000 / ticks_per_sec;
263 1.5.2.2 rmind
264 1.5.2.2 rmind /* now prepare serial console */
265 1.5.2.2 rmind consname = brdprop->consname;
266 1.5.2.2 rmind consport = brdprop->consport;
267 1.5.2.2 rmind if (strcmp(consname, "eumb") == 0) {
268 1.5.2.2 rmind uart1base = 0xfc000000 + consport; /* 0x4500, 0x4600 */
269 1.5.2.2 rmind UART_WRITE(uart1base, DCR, 0x01); /* enable DUART mode */
270 1.5.2.2 rmind uart2base = uart1base ^ 0x0300;
271 1.5.2.2 rmind } else
272 1.5.2.2 rmind uart1base = 0xfe000000 + consport; /* 0x3f8, 0x2f8 */
273 1.5.2.2 rmind
274 1.5.2.2 rmind /* more brd adjustments */
275 1.5.2.2 rmind brdfixup();
276 1.5.2.2 rmind
277 1.5.2.2 rmind bi_mem.memsize = mpc107memsize();
278 1.5.2.2 rmind snprintf(bi_cons.devname, sizeof(bi_cons.devname), consname);
279 1.5.2.2 rmind bi_cons.addr = consport;
280 1.5.2.2 rmind bi_cons.speed = brdprop->consspeed;
281 1.5.2.2 rmind bi_clk.ticks_per_sec = ticks_per_sec;
282 1.5.2.2 rmind snprintf(bi_fam.name, sizeof(bi_fam.name), brdprop->family);
283 1.5.2.2 rmind }
284 1.5.2.2 rmind
285 1.5.2.2 rmind struct brdprop *
286 1.5.2.2 rmind brd_lookup(int brd)
287 1.5.2.2 rmind {
288 1.5.2.2 rmind u_int i;
289 1.5.2.2 rmind
290 1.5.2.2 rmind for (i = 0; i < sizeof(brdlist)/sizeof(brdlist[0]); i++) {
291 1.5.2.2 rmind if (brdlist[i].brdtype == brd)
292 1.5.2.2 rmind return &brdlist[i];
293 1.5.2.2 rmind }
294 1.5.2.2 rmind return &brdlist[i - 1];
295 1.5.2.2 rmind }
296 1.5.2.2 rmind
297 1.5.2.2 rmind static void
298 1.5.2.2 rmind setup()
299 1.5.2.2 rmind {
300 1.5.2.2 rmind
301 1.5.2.2 rmind if (brdprop->setup == NULL)
302 1.5.2.2 rmind return;
303 1.5.2.2 rmind (*brdprop->setup)(brdprop);
304 1.5.2.2 rmind }
305 1.5.2.2 rmind
306 1.5.2.2 rmind static void
307 1.5.2.2 rmind brdfixup()
308 1.5.2.2 rmind {
309 1.5.2.2 rmind
310 1.5.2.2 rmind if (brdprop->brdfix == NULL)
311 1.5.2.2 rmind return;
312 1.5.2.2 rmind (*brdprop->brdfix)(brdprop);
313 1.5.2.2 rmind }
314 1.5.2.2 rmind
315 1.5.2.2 rmind void
316 1.5.2.2 rmind pcifixup()
317 1.5.2.2 rmind {
318 1.5.2.2 rmind
319 1.5.2.2 rmind if (brdprop->pcifix == NULL)
320 1.5.2.2 rmind return;
321 1.5.2.2 rmind (*brdprop->pcifix)(brdprop);
322 1.5.2.2 rmind }
323 1.5.2.2 rmind
324 1.5.2.2 rmind void
325 1.5.2.2 rmind encsetup(struct brdprop *brd)
326 1.5.2.2 rmind {
327 1.5.2.2 rmind
328 1.5.2.2 rmind #ifdef COSNAME
329 1.5.2.2 rmind brd->consname = CONSNAME;
330 1.5.2.2 rmind #endif
331 1.5.2.2 rmind #ifdef CONSPORT
332 1.5.2.2 rmind brd->consport = CONSPORT;
333 1.5.2.2 rmind #endif
334 1.5.2.2 rmind #ifdef CONSSPEED
335 1.5.2.2 rmind brd->consspeed = CONSSPEED;
336 1.5.2.2 rmind #endif
337 1.5.2.2 rmind }
338 1.5.2.2 rmind
339 1.5.2.2 rmind void
340 1.5.2.2 rmind encbrdfix(struct brdprop *brd)
341 1.5.2.2 rmind {
342 1.5.2.2 rmind unsigned ac97, ide, pcib, pmgt, usb12, usb34, val;
343 1.5.2.2 rmind
344 1.5.2.2 rmind /*
345 1.5.2.2 rmind * VIA82C686B Southbridge
346 1.5.2.2 rmind * 0.22.0 1106.0686 PCI-ISA bridge
347 1.5.2.2 rmind * 0.22.1 1106.0571 IDE (viaide)
348 1.5.2.2 rmind * 0.22.2 1106.3038 USB 0/1 (uhci)
349 1.5.2.2 rmind * 0.22.3 1106.3038 USB 2/3 (uhci)
350 1.5.2.2 rmind * 0.22.4 1106.3057 power management
351 1.5.2.2 rmind * 0.22.5 1106.3058 AC97 (auvia)
352 1.5.2.2 rmind */
353 1.5.2.2 rmind pcib = pcimaketag(0, 22, 0);
354 1.5.2.2 rmind ide = pcimaketag(0, 22, 1);
355 1.5.2.2 rmind usb12 = pcimaketag(0, 22, 2);
356 1.5.2.2 rmind usb34 = pcimaketag(0, 22, 3);
357 1.5.2.2 rmind pmgt = pcimaketag(0, 22, 4);
358 1.5.2.2 rmind ac97 = pcimaketag(0, 22, 5);
359 1.5.2.2 rmind
360 1.5.2.2 rmind #define CFG(i,v) do { \
361 1.5.2.2 rmind *(volatile unsigned char *)(0xfe000000 + 0x3f0) = (i); \
362 1.5.2.2 rmind *(volatile unsigned char *)(0xfe000000 + 0x3f1) = (v); \
363 1.5.2.2 rmind } while (0)
364 1.5.2.2 rmind val = pcicfgread(pcib, 0x84);
365 1.5.2.2 rmind val |= (02 << 8);
366 1.5.2.2 rmind pcicfgwrite(pcib, 0x84, val);
367 1.5.2.2 rmind CFG(0xe2, 0x0f); /* use COM1/2, don't use FDC/LPT */
368 1.5.2.2 rmind val = pcicfgread(pcib, 0x84);
369 1.5.2.2 rmind val &= ~(02 << 8);
370 1.5.2.2 rmind pcicfgwrite(pcib, 0x84, val);
371 1.5.2.2 rmind
372 1.5.2.2 rmind /* route pin C to i8259 IRQ 5, pin D to 11 */
373 1.5.2.2 rmind val = pcicfgread(pcib, 0x54);
374 1.5.2.2 rmind val = (val & 0xff) | 0xb0500000; /* Dx CB Ax xS */
375 1.5.2.2 rmind pcicfgwrite(pcib, 0x54, val);
376 1.5.2.2 rmind
377 1.5.2.2 rmind /* enable EISA ELCR1 (0x4d0) and ELCR2 (0x4d1) */
378 1.5.2.2 rmind val = pcicfgread(pcib, 0x44);
379 1.5.2.2 rmind val = val | 0x20000000;
380 1.5.2.2 rmind pcicfgwrite(pcib, 0x44, val);
381 1.5.2.2 rmind
382 1.5.2.2 rmind /* select level trigger for IRQ 5/11 at ELCR1/2 */
383 1.5.2.2 rmind *(volatile uint8_t *)0xfe0004d0 = 0x20; /* bit 5 */
384 1.5.2.2 rmind *(volatile uint8_t *)0xfe0004d1 = 0x08; /* bit 11 */
385 1.5.2.2 rmind
386 1.5.2.2 rmind /* USB and AC97 are hardwired with pin D and C */
387 1.5.2.2 rmind val = pcicfgread(usb12, 0x3c) &~ 0xff;
388 1.5.2.2 rmind val |= 11;
389 1.5.2.2 rmind pcicfgwrite(usb12, 0x3c, val);
390 1.5.2.2 rmind val = pcicfgread(usb34, 0x3c) &~ 0xff;
391 1.5.2.2 rmind val |= 11;
392 1.5.2.2 rmind pcicfgwrite(usb34, 0x3c, val);
393 1.5.2.2 rmind val = pcicfgread(ac97, 0x3c) &~ 0xff;
394 1.5.2.2 rmind val |= 5;
395 1.5.2.2 rmind pcicfgwrite(ac97, 0x3c, val);
396 1.5.2.2 rmind }
397 1.5.2.2 rmind
398 1.5.2.2 rmind void
399 1.5.2.2 rmind encpcifix(struct brdprop *brd)
400 1.5.2.2 rmind {
401 1.5.2.2 rmind unsigned ide, irq, net, pcib, steer, val;
402 1.5.2.2 rmind
403 1.5.2.2 rmind #define STEER(v, b) (((v) & (b)) ? "edge" : "level")
404 1.5.2.2 rmind pcib = pcimaketag(0, 22, 0);
405 1.5.2.2 rmind ide = pcimaketag(0, 22, 1);
406 1.5.2.2 rmind net = pcimaketag(0, 25, 0);
407 1.5.2.2 rmind
408 1.5.2.2 rmind /*
409 1.5.2.2 rmind * //// VIA PIRQ ////
410 1.5.2.2 rmind * 0x57/56/55/54 - Dx CB Ax xS
411 1.5.2.2 rmind */
412 1.5.2.2 rmind val = pcicfgread(pcib, 0x54); /* Dx CB Ax xs */
413 1.5.2.2 rmind steer = val & 0xf;
414 1.5.2.2 rmind irq = (val >> 12) & 0xf; /* 15:12 */
415 1.5.2.2 rmind if (irq) {
416 1.5.2.2 rmind printf("pin A -> irq %d, %s\n",
417 1.5.2.2 rmind irq, STEER(steer, 0x1));
418 1.5.2.2 rmind }
419 1.5.2.2 rmind irq = (val >> 16) & 0xf; /* 19:16 */
420 1.5.2.2 rmind if (irq) {
421 1.5.2.2 rmind printf("pin B -> irq %d, %s\n",
422 1.5.2.2 rmind irq, STEER(steer, 0x2));
423 1.5.2.2 rmind }
424 1.5.2.2 rmind irq = (val >> 20) & 0xf; /* 23:20 */
425 1.5.2.2 rmind if (irq) {
426 1.5.2.2 rmind printf("pin C -> irq %d, %s\n",
427 1.5.2.2 rmind irq, STEER(steer, 0x4));
428 1.5.2.2 rmind }
429 1.5.2.2 rmind irq = (val >> 28); /* 31:28 */
430 1.5.2.2 rmind if (irq) {
431 1.5.2.2 rmind printf("pin D -> irq %d, %s\n",
432 1.5.2.2 rmind irq, STEER(steer, 0x8));
433 1.5.2.2 rmind }
434 1.5.2.2 rmind #if 0
435 1.5.2.2 rmind /*
436 1.5.2.2 rmind * //// IDE fixup ////
437 1.5.2.2 rmind * - "native mode" (ide 0x09)
438 1.5.2.2 rmind * - use primary only (ide 0x40)
439 1.5.2.2 rmind */
440 1.5.2.2 rmind /* ide: 0x09 - programming interface; 1000'SsPp */
441 1.5.2.2 rmind val = pcicfgread(ide, 0x08) & 0xffff00ff;
442 1.5.2.2 rmind pcicfgwrite(ide, 0x08, val | (0x8f << 8));
443 1.5.2.2 rmind
444 1.5.2.2 rmind /* ide: 0x10-20 - leave them PCI memory space assigned */
445 1.5.2.2 rmind
446 1.5.2.2 rmind /* ide: 0x40 - use primary only */
447 1.5.2.2 rmind val = pcicfgread(ide, 0x40) &~ 03;
448 1.5.2.2 rmind val |= 02;
449 1.5.2.2 rmind pcicfgwrite(ide, 0x40, val);
450 1.5.2.2 rmind #else
451 1.5.2.2 rmind /*
452 1.5.2.2 rmind * //// IDE fixup ////
453 1.5.2.2 rmind * - "compatiblity mode" (ide 0x09)
454 1.5.2.2 rmind * - use primary only (ide 0x40)
455 1.5.2.2 rmind * - remove PCI pin assignment (ide 0x3d)
456 1.5.2.2 rmind */
457 1.5.2.2 rmind /* ide: 0x09 - programming interface; 1000'SsPp */
458 1.5.2.2 rmind val = pcicfgread(ide, 0x08) & 0xffff00ff;
459 1.5.2.2 rmind val |= (0x8a << 8);
460 1.5.2.2 rmind pcicfgwrite(ide, 0x08, val);
461 1.5.2.2 rmind
462 1.5.2.2 rmind /* ide: 0x10-20 */
463 1.5.2.2 rmind /*
464 1.5.2.2 rmind experiment shows writing ide: 0x09 changes these
465 1.5.2.2 rmind register behaviour. The pcicfgwrite() above writes
466 1.5.2.2 rmind 0x8a at ide: 0x09 to make sure legacy IDE. Then
467 1.5.2.2 rmind reading BAR0-3 is to return value 0s even though
468 1.5.2.2 rmind pcisetup() has written range assignments. Value
469 1.5.2.2 rmind overwrite makes no effect. Having 0x8f for native
470 1.5.2.2 rmind PCIIDE doesn't change register values and brings no
471 1.5.2.2 rmind weirdness.
472 1.5.2.2 rmind */
473 1.5.2.2 rmind
474 1.5.2.2 rmind /* ide: 0x40 - use primary only */
475 1.5.2.2 rmind val = pcicfgread(ide, 0x40) &~ 03;
476 1.5.2.2 rmind val |= 02;
477 1.5.2.2 rmind pcicfgwrite(ide, 0x40, val);
478 1.5.2.2 rmind
479 1.5.2.2 rmind /* ide: 0x3d/3c - turn off PCI pin */
480 1.5.2.2 rmind val = pcicfgread(ide, 0x3c) & 0xffff00ff;
481 1.5.2.2 rmind pcicfgwrite(ide, 0x3c, val);
482 1.5.2.2 rmind #endif
483 1.5.2.2 rmind /*
484 1.5.2.2 rmind * //// USBx2, audio, and modem fixup ////
485 1.5.2.2 rmind * - disable USB #0 and #1 (pcib 0x48 and 0x85)
486 1.5.2.2 rmind * - disable AC97 audio and MC97 modem (pcib 0x85)
487 1.5.2.2 rmind */
488 1.5.2.2 rmind
489 1.5.2.2 rmind /* pcib: 0x48 - disable USB #0 at function 2 */
490 1.5.2.2 rmind val = pcicfgread(pcib, 0x48);
491 1.5.2.2 rmind pcicfgwrite(pcib, 0x48, val | 04);
492 1.5.2.2 rmind
493 1.5.2.2 rmind /* pcib: 0x85 - disable USB #1 at function 3 */
494 1.5.2.2 rmind /* pcib: 0x85 - disable AC97/MC97 at function 5/6 */
495 1.5.2.2 rmind val = pcicfgread(pcib, 0x84);
496 1.5.2.2 rmind pcicfgwrite(pcib, 0x84, val | 0x1c00);
497 1.5.2.2 rmind
498 1.5.2.2 rmind /*
499 1.5.2.2 rmind * //// fxp fixup ////
500 1.5.2.2 rmind * - use PCI pin A line 25 (fxp 0x3d/3c)
501 1.5.2.2 rmind */
502 1.5.2.2 rmind /* 0x3d/3c - PCI pin/line */
503 1.5.2.2 rmind val = pcicfgread(net, 0x3c) & 0xffff0000;
504 1.5.2.2 rmind val |= (('A' - '@') << 8) | 25;
505 1.5.2.2 rmind pcicfgwrite(net, 0x3c, val);
506 1.5.2.2 rmind }
507 1.5.2.2 rmind
508 1.5.2.2 rmind void
509 1.5.2.2 rmind motsetup(struct brdprop *brd)
510 1.5.2.2 rmind {
511 1.5.2.2 rmind
512 1.5.2.2 rmind #ifdef COSNAME
513 1.5.2.2 rmind brd->consname = CONSNAME;
514 1.5.2.2 rmind #endif
515 1.5.2.2 rmind #ifdef CONSPORT
516 1.5.2.2 rmind brd->consport = CONSPORT;
517 1.5.2.2 rmind #endif
518 1.5.2.2 rmind #ifdef CONSSPEED
519 1.5.2.2 rmind brd->consspeed = CONSSPEED;
520 1.5.2.2 rmind #endif
521 1.5.2.2 rmind }
522 1.5.2.2 rmind
523 1.5.2.2 rmind void
524 1.5.2.2 rmind motbrdfix(struct brdprop *brd)
525 1.5.2.2 rmind {
526 1.5.2.2 rmind
527 1.5.2.2 rmind /*
528 1.5.2.2 rmind * WinBond/Symphony Lab 83C553 with PC87308 "SuperIO"
529 1.5.2.2 rmind *
530 1.5.2.2 rmind * 0.11.0 10ad.0565 PCI-ISA bridge
531 1.5.2.2 rmind * 0.11.1 10ad.0105 IDE (slide)
532 1.5.2.2 rmind */
533 1.5.2.2 rmind }
534 1.5.2.2 rmind
535 1.5.2.2 rmind void
536 1.5.2.2 rmind motpcifix(struct brdprop *brd)
537 1.5.2.2 rmind {
538 1.5.2.2 rmind unsigned ide, net, pcib, steer, val;
539 1.5.2.2 rmind int line;
540 1.5.2.2 rmind
541 1.5.2.2 rmind pcib = pcimaketag(0, 11, 0);
542 1.5.2.2 rmind ide = pcimaketag(0, 11, 1);
543 1.5.2.2 rmind net = pcimaketag(0, 15, 0);
544 1.5.2.2 rmind
545 1.5.2.2 rmind /*
546 1.5.2.2 rmind * //// WinBond PIRQ ////
547 1.5.2.2 rmind * 0x40 - bit 5 (0x20) indicates PIRQ presense
548 1.5.2.2 rmind * 0x60 - PIRQ interrupt routing steer
549 1.5.2.2 rmind */
550 1.5.2.2 rmind if (pcicfgread(pcib, 0x40) & 0x20) {
551 1.5.2.2 rmind steer = pcicfgread(pcib, 0x60);
552 1.5.2.2 rmind if ((steer & 0x80808080) == 0x80808080)
553 1.5.2.2 rmind printf("PIRQ[0-3] disabled\n");
554 1.5.2.2 rmind else {
555 1.5.2.2 rmind unsigned i, v = steer;
556 1.5.2.2 rmind for (i = 0; i < 4; i++, v >>= 8) {
557 1.5.2.2 rmind if ((v & 0x80) != 0 || (v & 0xf) == 0)
558 1.5.2.2 rmind continue;
559 1.5.2.2 rmind printf("PIRQ[%d]=%d\n", i, v & 0xf);
560 1.5.2.2 rmind }
561 1.5.2.2 rmind }
562 1.5.2.2 rmind }
563 1.5.2.2 rmind #if 1
564 1.5.2.2 rmind /*
565 1.5.2.2 rmind * //// IDE fixup -- case A ////
566 1.5.2.2 rmind * - "native PCI mode" (ide 0x09)
567 1.5.2.2 rmind * - don't use ISA IRQ14/15 (pcib 0x43)
568 1.5.2.2 rmind * - native IDE for both channels (ide 0x40)
569 1.5.2.2 rmind * - LEGIRQ bit 11 steers interrupt to pin C (ide 0x40)
570 1.5.2.2 rmind * - sign as PCI pin C line 11 (ide 0x3d/3c)
571 1.5.2.2 rmind */
572 1.5.2.2 rmind /* ide: 0x09 - programming interface; 1000'SsPp */
573 1.5.2.2 rmind val = pcicfgread(ide, 0x08);
574 1.5.2.2 rmind val &= 0xffff00ff;
575 1.5.2.2 rmind pcicfgwrite(ide, 0x08, val | (0x8f << 8));
576 1.5.2.2 rmind
577 1.5.2.2 rmind /* pcib: 0x43 - IDE interrupt routing */
578 1.5.2.2 rmind val = pcicfgread(pcib, 0x40) & 0x00ffffff;
579 1.5.2.2 rmind pcicfgwrite(pcib, 0x40, val);
580 1.5.2.2 rmind
581 1.5.2.2 rmind /* pcib: 0x45/44 - PCI interrupt routing */
582 1.5.2.2 rmind val = pcicfgread(pcib, 0x44) & 0xffff0000;
583 1.5.2.2 rmind pcicfgwrite(pcib, 0x44, val);
584 1.5.2.2 rmind
585 1.5.2.2 rmind /* ide: 0x41/40 - IDE channel */
586 1.5.2.2 rmind val = pcicfgread(ide, 0x40) & 0xffff0000;
587 1.5.2.2 rmind val |= (1 << 11) | 0x33; /* LEGIRQ turns on PCI interrupt */
588 1.5.2.2 rmind pcicfgwrite(ide, 0x40, val);
589 1.5.2.2 rmind
590 1.5.2.2 rmind /* ide: 0x3d/3c - use PCI pin C/line 11 */
591 1.5.2.2 rmind val = pcicfgread(ide, 0x3c) & 0xffffff00;
592 1.5.2.2 rmind val |= 11; /* pin designation is hardwired to pin A */
593 1.5.2.2 rmind pcicfgwrite(ide, 0x3c, val);
594 1.5.2.2 rmind #else
595 1.5.2.2 rmind /*
596 1.5.2.2 rmind * //// IDE fixup -- case B ////
597 1.5.2.2 rmind * - "compatiblity mode" (ide 0x09)
598 1.5.2.2 rmind * - IDE primary/secondary interrupt routing (pcib 0x43)
599 1.5.2.2 rmind * - PCI interrupt routing (pcib 0x45/44)
600 1.5.2.2 rmind * - no PCI pin/line assignment (ide 0x3d/3c)
601 1.5.2.2 rmind */
602 1.5.2.2 rmind /* ide: 0x09 - programming interface; 1000'SsPp */
603 1.5.2.2 rmind val = pcicfgread(ide, 0x08);
604 1.5.2.2 rmind val &= 0xffff00ff;
605 1.5.2.2 rmind pcicfgwrite(ide, 0x08, val | (0x8a << 8));
606 1.5.2.2 rmind
607 1.5.2.2 rmind /* pcib: 0x43 - IDE interrupt routing */
608 1.5.2.2 rmind val = pcicfgread(pcib, 0x40) & 0x00ffffff;
609 1.5.2.2 rmind pcicfgwrite(pcib, 0x40, val | (0xee << 24));
610 1.5.2.2 rmind
611 1.5.2.2 rmind /* ide: 0x45/44 - PCI interrupt routing */
612 1.5.2.2 rmind val = pcicfgread(ide, 0x44) & 0xffff0000;
613 1.5.2.2 rmind pcicfgwrite(ide, 0x44, val);
614 1.5.2.2 rmind
615 1.5.2.2 rmind /* ide: 0x3d/3c - turn off PCI pin/line */
616 1.5.2.2 rmind val = pcicfgread(ide, 0x3c) & 0xffff0000;
617 1.5.2.2 rmind pcicfgwrite(ide, 0x3c, val);
618 1.5.2.2 rmind #endif
619 1.5.2.2 rmind
620 1.5.2.2 rmind /*
621 1.5.2.2 rmind * //// fxp fixup ////
622 1.5.2.2 rmind * - use PCI pin A line 15 (fxp 0x3d/3c)
623 1.5.2.2 rmind */
624 1.5.2.2 rmind val = pcicfgread(net, 0x3c) & 0xffff0000;
625 1.5.2.2 rmind pcidecomposetag(net, NULL, &line, NULL);
626 1.5.2.2 rmind val |= (('A' - '@') << 8) | line;
627 1.5.2.2 rmind pcicfgwrite(net, 0x3c, val);
628 1.5.2.2 rmind }
629 1.5.2.2 rmind
630 1.5.2.2 rmind void
631 1.5.2.2 rmind kurosetup(struct brdprop *brd)
632 1.5.2.2 rmind {
633 1.5.2.2 rmind
634 1.5.2.2 rmind if (PCI_VENDOR(pcicfgread(pcimaketag(0, 11, 0), PCI_ID_REG)) == 0x10ec)
635 1.5.2.2 rmind brd->extclk = 32768000; /* decr 2457600Hz */
636 1.5.2.2 rmind else
637 1.5.2.2 rmind brd->extclk = 32521333; /* decr 2439100Hz */
638 1.5.2.2 rmind }
639 1.5.2.2 rmind
640 1.5.2.2 rmind void
641 1.5.2.2 rmind kurobrdfix(struct brdprop *brd)
642 1.5.2.2 rmind {
643 1.5.2.2 rmind
644 1.5.2.2 rmind init_uart(uart2base, 9600, LCR_8BITS | LCR_PEVEN);
645 1.5.2.2 rmind /* Stop Watchdog */
646 1.5.2.2 rmind send_sat("AAAAFFFFJJJJ>>>>VVVV>>>>ZZZZVVVVKKKK");
647 1.5.2.2 rmind }
648 1.5.2.2 rmind
649 1.5.2.2 rmind void
650 1.5.2.2 rmind synobrdfix(struct brdprop *brd)
651 1.5.2.2 rmind {
652 1.5.2.2 rmind
653 1.5.2.2 rmind init_uart(uart2base, 9600, LCR_8BITS | LCR_PNONE);
654 1.5.2.2 rmind /* beep, power LED on, status LED off */
655 1.5.2.2 rmind send_sat("247");
656 1.5.2.2 rmind }
657 1.5.2.2 rmind
658 1.5.2.2 rmind void
659 1.5.2.2 rmind synoreset()
660 1.5.2.2 rmind {
661 1.5.2.2 rmind
662 1.5.2.2 rmind send_sat("C");
663 1.5.2.2 rmind /*NOTRECHED*/
664 1.5.2.2 rmind }
665 1.5.2.2 rmind
666 1.5.2.2 rmind void
667 1.5.2.2 rmind qnapbrdfix(struct brdprop *brd)
668 1.5.2.2 rmind {
669 1.5.2.2 rmind
670 1.5.2.2 rmind /* illuminate LEDs */
671 1.5.2.2 rmind }
672 1.5.2.2 rmind
673 1.5.2.2 rmind void
674 1.5.2.2 rmind iomegabrdfix(struct brdprop *brd)
675 1.5.2.2 rmind {
676 1.5.2.2 rmind
677 1.5.2.2 rmind init_uart(uart2base, 9600, LCR_8BITS | LCR_PNONE);
678 1.5.2.2 rmind /* illuminate LEDs */
679 1.5.2.2 rmind }
680 1.5.2.2 rmind
681 1.5.2.2 rmind void
682 1.5.2.2 rmind dlinkbrdfix(struct brdprop *brd)
683 1.5.2.2 rmind {
684 1.5.2.2 rmind
685 1.5.2.2 rmind init_uart(uart2base, 9600, LCR_8BITS | LCR_PNONE);
686 1.5.2.2 rmind /* illuminate LEDs */
687 1.5.2.2 rmind }
688 1.5.2.2 rmind
689 1.5.2.2 rmind void
690 1.5.2.2 rmind nhnasbrdfix(struct brdprop *brd)
691 1.5.2.2 rmind {
692 1.5.2.2 rmind
693 1.5.2.2 rmind /* illuminate LEDs */
694 1.5.2.2 rmind }
695 1.5.2.2 rmind
696 1.5.2.2 rmind void
697 1.5.2.2 rmind _rtt(void)
698 1.5.2.2 rmind {
699 1.5.2.2 rmind
700 1.5.2.2 rmind if (brdprop->reset != NULL)
701 1.5.2.2 rmind (*brdprop->reset)();
702 1.5.2.2 rmind else
703 1.5.2.2 rmind run(0, 0, 0, 0, (void *)0xFFF00100); /* reset entry */
704 1.5.2.2 rmind /*NOTREACHED*/
705 1.5.2.2 rmind }
706 1.5.2.2 rmind
707 1.5.2.2 rmind satime_t
708 1.5.2.2 rmind getsecs(void)
709 1.5.2.2 rmind {
710 1.5.2.2 rmind u_quad_t tb = mftb();
711 1.5.2.2 rmind
712 1.5.2.2 rmind return (tb / ticks_per_sec);
713 1.5.2.2 rmind }
714 1.5.2.2 rmind
715 1.5.2.2 rmind /*
716 1.5.2.2 rmind * Wait for about n microseconds (at least!).
717 1.5.2.2 rmind */
718 1.5.2.2 rmind void
719 1.5.2.2 rmind delay(u_int n)
720 1.5.2.2 rmind {
721 1.5.2.2 rmind u_quad_t tb;
722 1.5.2.2 rmind u_long scratch, tbh, tbl;
723 1.5.2.2 rmind
724 1.5.2.2 rmind tb = mftb();
725 1.5.2.2 rmind tb += (n * 1000 + ns_per_tick - 1) / ns_per_tick;
726 1.5.2.2 rmind tbh = tb >> 32;
727 1.5.2.2 rmind tbl = tb;
728 1.5.2.2 rmind 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));
729 1.5.2.2 rmind }
730 1.5.2.2 rmind
731 1.5.2.2 rmind void
732 1.5.2.2 rmind _wb(uint32_t adr, uint32_t siz)
733 1.5.2.2 rmind {
734 1.5.2.2 rmind uint32_t bnd;
735 1.5.2.2 rmind
736 1.5.2.2 rmind asm volatile("eieio");
737 1.5.2.2 rmind for (bnd = adr + siz; adr < bnd; adr += dcache_line_size)
738 1.5.2.2 rmind asm volatile ("dcbst 0,%0" :: "r"(adr));
739 1.5.2.2 rmind asm volatile ("sync");
740 1.5.2.2 rmind }
741 1.5.2.2 rmind
742 1.5.2.2 rmind void
743 1.5.2.2 rmind _wbinv(uint32_t adr, uint32_t siz)
744 1.5.2.2 rmind {
745 1.5.2.2 rmind uint32_t bnd;
746 1.5.2.2 rmind
747 1.5.2.2 rmind asm volatile("eieio");
748 1.5.2.2 rmind for (bnd = adr + siz; adr < bnd; adr += dcache_line_size)
749 1.5.2.2 rmind asm volatile ("dcbf 0,%0" :: "r"(adr));
750 1.5.2.2 rmind asm volatile ("sync");
751 1.5.2.2 rmind }
752 1.5.2.2 rmind
753 1.5.2.2 rmind void
754 1.5.2.2 rmind _inv(uint32_t adr, uint32_t siz)
755 1.5.2.2 rmind {
756 1.5.2.2 rmind uint32_t bnd, off;
757 1.5.2.2 rmind
758 1.5.2.2 rmind off = adr & (dcache_line_size - 1);
759 1.5.2.2 rmind adr -= off;
760 1.5.2.2 rmind siz += off;
761 1.5.2.2 rmind asm volatile ("eieio");
762 1.5.2.2 rmind if (off != 0) {
763 1.5.2.2 rmind /* wbinv() leading unaligned dcache line */
764 1.5.2.2 rmind asm volatile ("dcbf 0,%0" :: "r"(adr));
765 1.5.2.2 rmind if (siz < dcache_line_size)
766 1.5.2.2 rmind goto done;
767 1.5.2.2 rmind adr += dcache_line_size;
768 1.5.2.2 rmind siz -= dcache_line_size;
769 1.5.2.2 rmind }
770 1.5.2.2 rmind bnd = adr + siz;
771 1.5.2.2 rmind off = bnd & (dcache_line_size - 1);
772 1.5.2.2 rmind if (off != 0) {
773 1.5.2.2 rmind /* wbinv() trailing unaligned dcache line */
774 1.5.2.2 rmind asm volatile ("dcbf 0,%0" :: "r"(bnd)); /* it's OK */
775 1.5.2.2 rmind if (siz < dcache_line_size)
776 1.5.2.2 rmind goto done;
777 1.5.2.2 rmind siz -= off;
778 1.5.2.2 rmind }
779 1.5.2.2 rmind for (bnd = adr + siz; adr < bnd; adr += dcache_line_size) {
780 1.5.2.2 rmind /* inv() intermediate dcache lines if ever */
781 1.5.2.2 rmind asm volatile ("dcbi 0,%0" :: "r"(adr));
782 1.5.2.2 rmind }
783 1.5.2.2 rmind done:
784 1.5.2.2 rmind asm volatile ("sync");
785 1.5.2.2 rmind }
786 1.5.2.2 rmind
787 1.5.2.2 rmind static inline uint32_t
788 1.5.2.2 rmind cputype(void)
789 1.5.2.2 rmind {
790 1.5.2.2 rmind uint32_t pvr;
791 1.5.2.2 rmind
792 1.5.2.2 rmind __asm volatile ("mfpvr %0" : "=r"(pvr));
793 1.5.2.2 rmind return pvr >> 16;
794 1.5.2.2 rmind }
795 1.5.2.2 rmind
796 1.5.2.2 rmind static inline u_quad_t
797 1.5.2.2 rmind mftb(void)
798 1.5.2.2 rmind {
799 1.5.2.2 rmind u_long scratch;
800 1.5.2.2 rmind u_quad_t tb;
801 1.5.2.2 rmind
802 1.5.2.2 rmind asm ("1: mftbu %0; mftb %0+1; mftbu %1; cmpw %0,%1; bne 1b"
803 1.5.2.2 rmind : "=r"(tb), "=r"(scratch));
804 1.5.2.2 rmind return (tb);
805 1.5.2.2 rmind }
806 1.5.2.2 rmind
807 1.5.2.2 rmind static void
808 1.5.2.2 rmind init_uart(unsigned base, unsigned speed, uint8_t lcr)
809 1.5.2.2 rmind {
810 1.5.2.2 rmind unsigned div;
811 1.5.2.2 rmind
812 1.5.2.2 rmind div = busclock / speed / 16;
813 1.5.2.2 rmind UART_WRITE(base, LCR, 0x80); /* turn on DLAB bit */
814 1.5.2.2 rmind UART_WRITE(base, FCR, 0x00);
815 1.5.2.2 rmind UART_WRITE(base, DMB, div >> 8); /* set speed */
816 1.5.2.2 rmind UART_WRITE(base, DLB, div & 0xff);
817 1.5.2.2 rmind UART_WRITE(base, LCR, lcr);
818 1.5.2.2 rmind UART_WRITE(base, FCR, 0x07); /* FIFO on, TXRX FIFO reset */
819 1.5.2.2 rmind UART_WRITE(base, IER, 0x00); /* make sure INT disabled */
820 1.5.2.2 rmind }
821 1.5.2.2 rmind
822 1.5.2.2 rmind /* talk to satellite processor */
823 1.5.2.2 rmind static void
824 1.5.2.2 rmind send_sat(char *msg)
825 1.5.2.2 rmind {
826 1.5.2.2 rmind unsigned savedbase;
827 1.5.2.2 rmind
828 1.5.2.2 rmind savedbase = uart1base;
829 1.5.2.2 rmind uart1base = uart2base;
830 1.5.2.2 rmind while (*msg)
831 1.5.2.2 rmind putchar(*msg++);
832 1.5.2.2 rmind uart1base = savedbase;
833 1.5.2.2 rmind }
834 1.5.2.2 rmind
835 1.5.2.2 rmind void
836 1.5.2.2 rmind putchar(int c)
837 1.5.2.2 rmind {
838 1.5.2.2 rmind unsigned timo, lsr;
839 1.5.2.2 rmind
840 1.5.2.2 rmind if (c == '\n')
841 1.5.2.2 rmind putchar('\r');
842 1.5.2.2 rmind
843 1.5.2.2 rmind timo = 0x00100000;
844 1.5.2.2 rmind do {
845 1.5.2.2 rmind lsr = UART_READ(uart1base, LSR);
846 1.5.2.2 rmind } while (timo-- > 0 && (lsr & LSR_THRE) == 0);
847 1.5.2.2 rmind if (timo > 0)
848 1.5.2.2 rmind UART_WRITE(uart1base, THR, c);
849 1.5.2.2 rmind }
850 1.5.2.2 rmind
851 1.5.2.2 rmind unsigned
852 1.5.2.2 rmind mpc107memsize()
853 1.5.2.2 rmind {
854 1.5.2.2 rmind unsigned bankn, end, n, tag, val;
855 1.5.2.2 rmind
856 1.5.2.2 rmind tag = pcimaketag(0, 0, 0);
857 1.5.2.2 rmind
858 1.5.2.2 rmind if (brdtype == BRD_ENCOREPP1) {
859 1.5.2.2 rmind /* the brd's PPCBOOT looks to have erroneous values */
860 1.5.2.2 rmind unsigned tbl[] = {
861 1.5.2.2 rmind #define MPC106_MEMSTARTADDR1 0x80
862 1.5.2.2 rmind #define MPC106_EXTMEMSTARTADDR1 0x88
863 1.5.2.2 rmind #define MPC106_MEMENDADDR1 0x90
864 1.5.2.2 rmind #define MPC106_EXTMEMENDADDR1 0x98
865 1.5.2.2 rmind #define MPC106_MEMEN 0xa0
866 1.5.2.2 rmind #define BK0_S 0x00000000
867 1.5.2.2 rmind #define BK0_E (128 << 20) - 1
868 1.5.2.2 rmind #define BK1_S 0x3ff00000
869 1.5.2.2 rmind #define BK1_E 0x3fffffff
870 1.5.2.2 rmind #define BK2_S 0x3ff00000
871 1.5.2.2 rmind #define BK2_E 0x3fffffff
872 1.5.2.2 rmind #define BK3_S 0x3ff00000
873 1.5.2.2 rmind #define BK3_E 0x3fffffff
874 1.5.2.2 rmind #define AR(v, s) ((((v) & SAR_MASK) >> SAR_SHIFT) << (s))
875 1.5.2.2 rmind #define XR(v, s) ((((v) & EAR_MASK) >> EAR_SHIFT) << (s))
876 1.5.2.2 rmind #define SAR_MASK 0x0ff00000
877 1.5.2.2 rmind #define SAR_SHIFT 20
878 1.5.2.2 rmind #define EAR_MASK 0x30000000
879 1.5.2.2 rmind #define EAR_SHIFT 28
880 1.5.2.2 rmind AR(BK0_S, 0) | AR(BK1_S, 8) | AR(BK2_S, 16) | AR(BK3_S, 24),
881 1.5.2.2 rmind XR(BK0_S, 0) | XR(BK1_S, 8) | XR(BK2_S, 16) | XR(BK3_S, 24),
882 1.5.2.2 rmind AR(BK0_E, 0) | AR(BK1_E, 8) | AR(BK2_E, 16) | AR(BK3_E, 24),
883 1.5.2.2 rmind XR(BK0_E, 0) | XR(BK1_E, 8) | XR(BK2_E, 16) | XR(BK3_E, 24),
884 1.5.2.2 rmind };
885 1.5.2.2 rmind tag = pcimaketag(0, 0, 0);
886 1.5.2.2 rmind pcicfgwrite(tag, MPC106_MEMSTARTADDR1, tbl[0]);
887 1.5.2.2 rmind pcicfgwrite(tag, MPC106_EXTMEMSTARTADDR1, tbl[1]);
888 1.5.2.2 rmind pcicfgwrite(tag, MPC106_MEMENDADDR1, tbl[2]);
889 1.5.2.2 rmind pcicfgwrite(tag, MPC106_EXTMEMENDADDR1, tbl[3]);
890 1.5.2.2 rmind pcicfgwrite(tag, MPC106_MEMEN, 1);
891 1.5.2.2 rmind }
892 1.5.2.2 rmind
893 1.5.2.2 rmind bankn = 0;
894 1.5.2.2 rmind val = pcicfgread(tag, MPC106_MEMEN);
895 1.5.2.2 rmind for (n = 0; n < 4; n++) {
896 1.5.2.2 rmind if ((val & (1U << n)) == 0)
897 1.5.2.2 rmind break;
898 1.5.2.2 rmind bankn = n;
899 1.5.2.2 rmind }
900 1.5.2.2 rmind bankn = bankn * 8;
901 1.5.2.2 rmind
902 1.5.2.2 rmind val = pcicfgread(tag, MPC106_EXTMEMENDADDR1);
903 1.5.2.2 rmind end = ((val >> bankn) & 0x03) << 28;
904 1.5.2.2 rmind val = pcicfgread(tag, MPC106_MEMENDADDR1);
905 1.5.2.2 rmind end |= ((val >> bankn) & 0xff) << 20;
906 1.5.2.2 rmind end |= 0xfffff;
907 1.5.2.2 rmind
908 1.5.2.2 rmind return (end + 1); /* assume the end address matches total amount */
909 1.5.2.2 rmind }
910 1.5.2.2 rmind
911 1.5.2.2 rmind struct fis_dir_entry {
912 1.5.2.2 rmind char name[16];
913 1.5.2.2 rmind uint32_t startaddr;
914 1.5.2.2 rmind uint32_t loadaddr;
915 1.5.2.2 rmind uint32_t flashsize;
916 1.5.2.2 rmind uint32_t entryaddr;
917 1.5.2.2 rmind uint32_t filesize;
918 1.5.2.2 rmind char pad[256 - (16 + 5 * sizeof(uint32_t))];
919 1.5.2.2 rmind };
920 1.5.2.2 rmind
921 1.5.2.2 rmind #define FIS_LOWER_LIMIT 0xfff00000
922 1.5.2.2 rmind
923 1.5.2.2 rmind /*
924 1.5.2.2 rmind * Look for a Redboot-style Flash Image System FIS-directory and
925 1.5.2.2 rmind * return a pointer to the start address of the requested file.
926 1.5.2.2 rmind */
927 1.5.2.2 rmind static void *
928 1.5.2.2 rmind redboot_fis_lookup(const char *filename)
929 1.5.2.2 rmind {
930 1.5.2.2 rmind static const char FISdirname[16] = {
931 1.5.2.2 rmind 'F', 'I', 'S', ' ',
932 1.5.2.2 rmind 'd', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 0, 0, 0
933 1.5.2.2 rmind };
934 1.5.2.2 rmind struct fis_dir_entry *dir;
935 1.5.2.2 rmind
936 1.5.2.2 rmind /*
937 1.5.2.2 rmind * The FIS directory is usually in the last sector of the flash.
938 1.5.2.2 rmind * But we do not know the sector size (erase size), so start
939 1.5.2.2 rmind * at 0xffffff00 and scan backwards in steps of the FIS directory
940 1.5.2.2 rmind * entry size (0x100).
941 1.5.2.2 rmind */
942 1.5.2.2 rmind for (dir = (struct fis_dir_entry *)0xffffff00;
943 1.5.2.2 rmind (uint32_t)dir >= FIS_LOWER_LIMIT; dir--)
944 1.5.2.2 rmind if (memcmp(dir->name, FISdirname, sizeof(FISdirname)) == 0)
945 1.5.2.2 rmind break;
946 1.5.2.2 rmind if ((uint32_t)dir < FIS_LOWER_LIMIT) {
947 1.5.2.2 rmind printf("No FIS directory found!\n");
948 1.5.2.2 rmind return NULL;
949 1.5.2.2 rmind }
950 1.5.2.2 rmind
951 1.5.2.2 rmind /* Now find filename by scanning the directory from beginning. */
952 1.5.2.2 rmind dir = (struct fis_dir_entry *)dir->startaddr;
953 1.5.2.2 rmind while (dir->name[0] != 0xff && (uint32_t)dir < 0xffffff00) {
954 1.5.2.2 rmind if (strcmp(dir->name, filename) == 0)
955 1.5.2.2 rmind return (void *)dir->startaddr; /* found */
956 1.5.2.2 rmind dir++;
957 1.5.2.2 rmind }
958 1.5.2.2 rmind printf("\"%s\" not found in FIS directory!\n", filename);
959 1.5.2.2 rmind return NULL;
960 1.5.2.2 rmind }
961 1.5.2.2 rmind
962 1.5.2.2 rmind /*
963 1.5.2.2 rmind * For cost saving reasons some NAS boxes are missing the ROM for the
964 1.5.2.2 rmind * NIC's ethernet address and keep it in their Flash memory.
965 1.5.2.2 rmind */
966 1.5.2.2 rmind void
967 1.5.2.2 rmind read_mac_from_flash(uint8_t *mac)
968 1.5.2.2 rmind {
969 1.5.2.2 rmind uint8_t *p;
970 1.5.2.2 rmind
971 1.5.2.2 rmind if (brdtype == BRD_SYNOLOGY) {
972 1.5.2.2 rmind p = redboot_fis_lookup("vendor");
973 1.5.2.2 rmind if (p != NULL) {
974 1.5.2.2 rmind memcpy(mac, p, 6);
975 1.5.2.2 rmind return;
976 1.5.2.2 rmind }
977 1.5.2.2 rmind } else
978 1.5.2.2 rmind printf("Warning: This board has no known method defined "
979 1.5.2.2 rmind "to determine its MAC address!\n");
980 1.5.2.2 rmind
981 1.5.2.2 rmind /* set to 00:00:00:00:00:00 in case of error */
982 1.5.2.2 rmind memset(mac, 0, 6);
983 1.5.2.2 rmind }
984