1154abd99SDavid du Colombier /*
2154abd99SDavid du Colombier * stuff specific to marvell's kirkwood architecture
3154abd99SDavid du Colombier * as seen in the sheevaplug
4154abd99SDavid du Colombier */
5154abd99SDavid du Colombier #include "u.h"
6154abd99SDavid du Colombier #include "../port/lib.h"
7154abd99SDavid du Colombier #include "mem.h"
8154abd99SDavid du Colombier #include "dat.h"
9154abd99SDavid du Colombier #include "fns.h"
10154abd99SDavid du Colombier #include "../port/error.h"
11154abd99SDavid du Colombier #include "io.h"
12154abd99SDavid du Colombier
13154abd99SDavid du Colombier #include "../port/netif.h"
14154abd99SDavid du Colombier #include "etherif.h"
1506f6463aSDavid du Colombier #include "../port/flashif.h"
16154abd99SDavid du Colombier
17b72bcbbfSDavid du Colombier #include "arm.h"
18b72bcbbfSDavid du Colombier
19ffc08dc1SDavid du Colombier enum {
20a7a38e3eSDavid du Colombier L2writeback = 1,
2180f6c381SDavid du Colombier Debug = 0,
22ffc08dc1SDavid du Colombier };
23ffc08dc1SDavid du Colombier
24154abd99SDavid du Colombier typedef struct GpioReg GpioReg;
25154abd99SDavid du Colombier struct GpioReg {
26154abd99SDavid du Colombier ulong dataout;
27154abd99SDavid du Colombier ulong dataoutena;
28154abd99SDavid du Colombier ulong blinkena;
29154abd99SDavid du Colombier ulong datainpol;
30154abd99SDavid du Colombier ulong datain;
31154abd99SDavid du Colombier ulong intrcause;
32154abd99SDavid du Colombier ulong intrmask;
33154abd99SDavid du Colombier ulong intrlevelmask;
34154abd99SDavid du Colombier };
35154abd99SDavid du Colombier
36154abd99SDavid du Colombier typedef struct L2uncache L2uncache;
37154abd99SDavid du Colombier typedef struct L2win L2win;
38154abd99SDavid du Colombier struct L2uncache {
39154abd99SDavid du Colombier struct L2win {
40fee6e4b8SDavid du Colombier ulong base; /* phys addr */
41154abd99SDavid du Colombier ulong size;
42154abd99SDavid du Colombier } win[4];
43154abd99SDavid du Colombier };
44154abd99SDavid du Colombier
45154abd99SDavid du Colombier enum {
46154abd99SDavid du Colombier /* L2win->base bits */
47154abd99SDavid du Colombier L2enable = 1<<0,
48154abd99SDavid du Colombier };
49154abd99SDavid du Colombier
5056713243SDavid du Colombier typedef struct Dramctl Dramctl;
5156713243SDavid du Colombier struct Dramctl {
5256713243SDavid du Colombier ulong ctl;
5356713243SDavid du Colombier ulong ddrctllo;
5456713243SDavid du Colombier struct {
5556713243SDavid du Colombier ulong lo;
5656713243SDavid du Colombier ulong hi;
5756713243SDavid du Colombier } time;
5856713243SDavid du Colombier ulong addrctl;
5956713243SDavid du Colombier ulong opagectl;
6056713243SDavid du Colombier ulong oper;
6156713243SDavid du Colombier ulong mode;
6256713243SDavid du Colombier ulong extmode;
6356713243SDavid du Colombier ulong ddrctlhi;
6456713243SDavid du Colombier ulong ddr2timelo;
6556713243SDavid du Colombier ulong operctl;
6656713243SDavid du Colombier struct {
6756713243SDavid du Colombier ulong lo;
6856713243SDavid du Colombier ulong hi;
6956713243SDavid du Colombier } mbusctl;
7056713243SDavid du Colombier ulong mbustimeout;
7156713243SDavid du Colombier ulong ddrtimehi;
7256713243SDavid du Colombier ulong sdinitctl;
7356713243SDavid du Colombier ulong extsdmode1;
7456713243SDavid du Colombier ulong extsdmode2;
7556713243SDavid du Colombier struct {
7656713243SDavid du Colombier ulong lo;
7756713243SDavid du Colombier ulong hi;
7856713243SDavid du Colombier } odtctl;
7956713243SDavid du Colombier ulong ddrodtctl;
8056713243SDavid du Colombier ulong rbuffsel;
8156713243SDavid du Colombier
8256713243SDavid du Colombier ulong accalib;
8356713243SDavid du Colombier ulong dqcalib;
8456713243SDavid du Colombier ulong dqscalib;
8556713243SDavid du Colombier };
8656713243SDavid du Colombier
877365b686SDavid du Colombier /* unused so far */
8856713243SDavid du Colombier typedef struct SDramdReg SDramdReg;
8956713243SDavid du Colombier struct SDramdReg {
9056713243SDavid du Colombier struct {
9156713243SDavid du Colombier ulong base;
9256713243SDavid du Colombier ulong size;
9356713243SDavid du Colombier } win[4];
9456713243SDavid du Colombier };
9556713243SDavid du Colombier
96154abd99SDavid du Colombier typedef struct Addrmap Addrmap;
97154abd99SDavid du Colombier typedef struct Addrwin Addrwin;
98154abd99SDavid du Colombier struct Addrmap {
99154abd99SDavid du Colombier struct Addrwin {
10006f6463aSDavid du Colombier ulong ctl; /* see Winenable in io.h */
101*b649930dSDavid du Colombier ulong base; /* virtual address */
102*b649930dSDavid du Colombier ulong remaplo; /* physical address sent to target */
103*b649930dSDavid du Colombier ulong remaphi; /* " */
104154abd99SDavid du Colombier } win[8];
1058a12d8dfSDavid du Colombier ulong dirba; /* device internal reg's base addr.: PHYSIO */
106154abd99SDavid du Colombier };
107154abd99SDavid du Colombier
1087365b686SDavid du Colombier Soc soc = {
1097365b686SDavid du Colombier .cpu = PHYSIO+0x20100,
1107365b686SDavid du Colombier .devid = PHYSIO+0x10034,
1117365b686SDavid du Colombier .l2cache = PHYSIO+0x20a00, /* uncachable addrs for L2 */
1127365b686SDavid du Colombier .sdramc = PHYSIO+0x01400,
1137365b686SDavid du Colombier // .sdramd = PHYSIO+0x01500, /* unused */
1147365b686SDavid du Colombier
1157365b686SDavid du Colombier .iocfg = PHYSIO+0x100e0,
116*b649930dSDavid du Colombier .addrmap = PHYSIO+0x20000, /* cpu address map */
1177365b686SDavid du Colombier .intr = PHYSIO+0x20200,
1187365b686SDavid du Colombier .nand = PHYSIO+0x10418,
1197365b686SDavid du Colombier .cesa = PHYSIO+0x30000, /* crypto accelerator */
1207365b686SDavid du Colombier .ehci = PHYSIO+0x50000,
1217365b686SDavid du Colombier .spi = PHYSIO+0x10600,
1227365b686SDavid du Colombier .twsi = PHYSIO+0x11000,
1237365b686SDavid du Colombier
1247365b686SDavid du Colombier .analog = PHYSIO+0x1007c,
1257365b686SDavid du Colombier .pci = PHYSIO+0x40000,
1267365b686SDavid du Colombier .pcibase = PHYSIO+0x41800,
1277365b686SDavid du Colombier
1287365b686SDavid du Colombier .rtc = PHYSIO+0x10300,
1297365b686SDavid du Colombier .clock = PHYSIO+0x20300,
1307365b686SDavid du Colombier // .clockctl = PHYSIO+0x1004c, /* unused */
1317365b686SDavid du Colombier
1321ecc8ef2SDavid du Colombier .ether = { PHYSIO+0x72000, PHYSIO+0x76000, },
1337365b686SDavid du Colombier .sata = { PHYSIO+0x80000, /* sata config reg here */
1347365b686SDavid du Colombier PHYSIO+0x82000, /* edma config reg here */
1357365b686SDavid du Colombier PHYSIO+0x84000, /* edma config reg here */
1367365b686SDavid du Colombier },
1377365b686SDavid du Colombier .uart = { PHYSIO+0x12000, PHYSIO+0x12100, },
1387365b686SDavid du Colombier .gpio = { PHYSIO+0x10100, PHYSIO+0x10140, },
1397365b686SDavid du Colombier };
1407365b686SDavid du Colombier
141154abd99SDavid du Colombier /*
142897ae9c1SDavid du Colombier * sheeva/openrd u-boot leaves us with this address map:
143154abd99SDavid du Colombier *
144154abd99SDavid du Colombier * 0 targ 4 attr 0xe8 size 256MB addr 0x9:: remap addr 0x9:: pci mem
145154abd99SDavid du Colombier * 1 targ 1 attr 0x2f size 8MB addr 0xf9:: remap addr 0xf9:: nand flash
146154abd99SDavid du Colombier * 2 targ 4 attr 0xe0 size 16MB addr 0xf:: remap addr 0xc:: pci i/o
147154abd99SDavid du Colombier * 3 targ 1 attr 0x1e size 16MB addr 0xf8:: remap addr 0x0 spi flash
148154abd99SDavid du Colombier * 4 targ 1 attr 0x1d size 16MB addr 0xff:: boot rom
149154abd99SDavid du Colombier * 5 targ 1 attr 0x1e size 128MB addr 0xe8:: disabled spi flash
150154abd99SDavid du Colombier * 6 targ 1 attr 0x1d size 128MB addr 0xf:: disabled boot rom
151a0d13e95SDavid du Colombier * 7 targ 3 attr 0x1 size 64K addr 0xfb:: crypto sram
152*b649930dSDavid du Colombier *
153*b649930dSDavid du Colombier * dreamplug u-boot leaves us with this address map:
154*b649930dSDavid du Colombier *
155*b649930dSDavid du Colombier * 0 targ 4 attr 0xe8 size 256MB addr 0x9:: remap addr 0x9:: pci mem
156*b649930dSDavid du Colombier * 1 targ 4 attr 0xe0 size 64KB addr 0xc:: remap addr 0xc:: pci i/o
157*b649930dSDavid du Colombier * 2 targ 1 attr 0x2f size 128MB addr 0xd8:: remap addr 0xd8:: nand flash
158*b649930dSDavid du Colombier * 3 targ 1 attr 0x1e size 128MB addr 0xe8:: remap addr 0xe8:: spi flash
159*b649930dSDavid du Colombier * 4 targ 1 attr 0x1d size 128MB addr 0xf8:: boot rom
160*b649930dSDavid du Colombier * 5 targ 3 attr 0x1 size 64K addr 0xc801:: crypto sram
161*b649930dSDavid du Colombier * 6 targ 0 attr 0x0 size 64K addr 0xf:: disabled ram?
162*b649930dSDavid du Colombier * 7 targ 0 attr 0x0 size 64K addr 0xf8:: disabled ram?
163154abd99SDavid du Colombier */
164*b649930dSDavid du Colombier
165154abd99SDavid du Colombier #define WINTARG(ctl) (((ctl) >> 4) & 017)
166154abd99SDavid du Colombier #define WINATTR(ctl) (((ctl) >> 8) & 0377)
167154abd99SDavid du Colombier #define WIN64KSIZE(ctl) (((ctl) >> 16) + 1)
168154abd99SDavid du Colombier
169154abd99SDavid du Colombier static void
praddrwin(Addrwin * win,int i)170ffc08dc1SDavid du Colombier praddrwin(Addrwin *win, int i)
171ffc08dc1SDavid du Colombier {
172ffc08dc1SDavid du Colombier ulong ctl, targ, attr, size64k;
173ffc08dc1SDavid du Colombier
17480f6c381SDavid du Colombier if (!Debug) {
17580f6c381SDavid du Colombier USED(win, i);
17680f6c381SDavid du Colombier return;
17780f6c381SDavid du Colombier }
178ffc08dc1SDavid du Colombier ctl = win->ctl;
179ffc08dc1SDavid du Colombier targ = WINTARG(ctl);
180ffc08dc1SDavid du Colombier attr = WINATTR(ctl);
181ffc08dc1SDavid du Colombier size64k = WIN64KSIZE(ctl);
182b72bcbbfSDavid du Colombier print("cpu addr map: %s window %d: targ %ld attr %#lux size %,ld addr %#lux",
183ffc08dc1SDavid du Colombier ctl & Winenable? "enabled": "disabled", i, targ, attr,
184ffc08dc1SDavid du Colombier size64k * 64*1024, win->base);
185ffc08dc1SDavid du Colombier if (i < 4)
186ffc08dc1SDavid du Colombier print(" remap addr %#llux", (uvlong)win->remaphi<<32 |
187ffc08dc1SDavid du Colombier win->remaplo);
188ffc08dc1SDavid du Colombier print("\n");
189ffc08dc1SDavid du Colombier }
190ffc08dc1SDavid du Colombier
191ffc08dc1SDavid du Colombier static void
fixaddrmap(void)192ffc08dc1SDavid du Colombier fixaddrmap(void)
193154abd99SDavid du Colombier {
194897ae9c1SDavid du Colombier int i;
195154abd99SDavid du Colombier ulong ctl, targ, attr, size64k;
196154abd99SDavid du Colombier Addrmap *map;
197154abd99SDavid du Colombier Addrwin *win;
198154abd99SDavid du Colombier
1997365b686SDavid du Colombier map = (Addrmap *)soc.addrmap;
200154abd99SDavid du Colombier for (i = 0; i < nelem(map->win); i++) {
201154abd99SDavid du Colombier win = &map->win[i];
202154abd99SDavid du Colombier ctl = win->ctl;
203154abd99SDavid du Colombier targ = WINTARG(ctl);
204154abd99SDavid du Colombier attr = WINATTR(ctl);
205154abd99SDavid du Colombier size64k = WIN64KSIZE(ctl);
206ffc08dc1SDavid du Colombier
207897ae9c1SDavid du Colombier USED(attr, size64k);
208897ae9c1SDavid du Colombier if (targ == Targcesasram) {
209a0d13e95SDavid du Colombier win->ctl |= Winenable;
210a0d13e95SDavid du Colombier win->base = PHYSCESASRAM;
211a0d13e95SDavid du Colombier coherence();
212ffc08dc1SDavid du Colombier praddrwin(win, i);
213154abd99SDavid du Colombier }
214154abd99SDavid du Colombier }
215ffc08dc1SDavid du Colombier if (map->dirba != PHYSIO)
216ffc08dc1SDavid du Colombier panic("dirba not %#ux", PHYSIO);
217ffc08dc1SDavid du Colombier }
218ffc08dc1SDavid du Colombier
219ffc08dc1SDavid du Colombier static void
praddrmap(void)220ffc08dc1SDavid du Colombier praddrmap(void)
221ffc08dc1SDavid du Colombier {
222ffc08dc1SDavid du Colombier int i;
223ffc08dc1SDavid du Colombier Addrmap *map;
224ffc08dc1SDavid du Colombier
2257365b686SDavid du Colombier map = (Addrmap *)soc.addrmap;
226ffc08dc1SDavid du Colombier for (i = 0; i < nelem(map->win); i++)
227ffc08dc1SDavid du Colombier praddrwin(&map->win[i], i);
228154abd99SDavid du Colombier }
229154abd99SDavid du Colombier
230b72bcbbfSDavid du Colombier void
cacheinfo(int level,int kind,Memcache * cp)23110dec6bfSDavid du Colombier cacheinfo(int level, int kind, Memcache *cp) /* l1 only */
232b72bcbbfSDavid du Colombier {
233b72bcbbfSDavid du Colombier uint len, assoc, size;
234b72bcbbfSDavid du Colombier ulong setsways;
235b72bcbbfSDavid du Colombier
23610dec6bfSDavid du Colombier /* get cache types & sizes (read-only reg) */
237b72bcbbfSDavid du Colombier setsways = cprdsc(0, CpID, CpIDidct, CpIDct);
238b72bcbbfSDavid du Colombier
239b72bcbbfSDavid du Colombier cp->level = level;
24010dec6bfSDavid du Colombier cp->kind = kind;
241b72bcbbfSDavid du Colombier
242b72bcbbfSDavid du Colombier if ((setsways & (1<<24)) == 0)
24310dec6bfSDavid du Colombier kind = Unified;
24410dec6bfSDavid du Colombier if (kind != Icache)
245b72bcbbfSDavid du Colombier setsways >>= 12;
246b72bcbbfSDavid du Colombier
247b72bcbbfSDavid du Colombier assoc = (setsways >> 3) & MASK(3);
248b72bcbbfSDavid du Colombier cp->nways = 1 << assoc;
249b72bcbbfSDavid du Colombier size = (setsways >> 6) & MASK(4);
250b72bcbbfSDavid du Colombier cp->size = 1 << (size + 9);
251b72bcbbfSDavid du Colombier len = setsways & MASK(2);
252b72bcbbfSDavid du Colombier cp->log2linelen = len + 3;
253b72bcbbfSDavid du Colombier cp->linelen = 1 << cp->log2linelen;
25410dec6bfSDavid du Colombier cp->setsways = setsways;
255b72bcbbfSDavid du Colombier
256b72bcbbfSDavid du Colombier cp->nsets = 1 << (size + 6 - assoc - len);
257b72bcbbfSDavid du Colombier cp->setsh = cp->log2linelen;
258b72bcbbfSDavid du Colombier cp->waysh = 32 - log2(cp->nways);
259b72bcbbfSDavid du Colombier }
260b72bcbbfSDavid du Colombier
26110dec6bfSDavid du Colombier static char *
wbtype(uint type)26210dec6bfSDavid du Colombier wbtype(uint type)
26310dec6bfSDavid du Colombier {
26410dec6bfSDavid du Colombier static char *types[] = {
26510dec6bfSDavid du Colombier "write-through",
26610dec6bfSDavid du Colombier "read data block",
26710dec6bfSDavid du Colombier "reg 7 ops, no lock-down",
26810dec6bfSDavid du Colombier [06] "reg 7 ops, format A",
26910dec6bfSDavid du Colombier [07] "reg 7 ops, format B deprecated",
27010dec6bfSDavid du Colombier [016] "reg 7 ops, format C",
27110dec6bfSDavid du Colombier [05] "reg 7 ops, format D",
27210dec6bfSDavid du Colombier };
27310dec6bfSDavid du Colombier
27410dec6bfSDavid du Colombier if (type >= nelem(types) || types[type] == nil)
27510dec6bfSDavid du Colombier return "GOK";
27610dec6bfSDavid du Colombier return types[type];
27710dec6bfSDavid du Colombier }
27810dec6bfSDavid du Colombier
27910dec6bfSDavid du Colombier static void
prcache(Memcache * mcp)28010dec6bfSDavid du Colombier prcache(Memcache *mcp)
28110dec6bfSDavid du Colombier {
28210dec6bfSDavid du Colombier int type;
28310dec6bfSDavid du Colombier char id;
28410dec6bfSDavid du Colombier
28510dec6bfSDavid du Colombier if (mcp->kind == Unified)
28610dec6bfSDavid du Colombier id = 'U';
28710dec6bfSDavid du Colombier else if (mcp->kind == Icache)
28810dec6bfSDavid du Colombier id = 'I';
28910dec6bfSDavid du Colombier else if (mcp->kind == Dcache)
29010dec6bfSDavid du Colombier id = 'D';
29110dec6bfSDavid du Colombier else
29210dec6bfSDavid du Colombier id = '?';
29310dec6bfSDavid du Colombier print("l%d %c: %d bytes, %d ways %d sets %d bytes/line",
29410dec6bfSDavid du Colombier mcp->level, id, mcp->size, mcp->nways, mcp->nsets,
29510dec6bfSDavid du Colombier mcp->linelen);
29610dec6bfSDavid du Colombier if (mcp->linelen != CACHELINESZ)
29710dec6bfSDavid du Colombier print(" *should* be %d", CACHELINESZ);
29810dec6bfSDavid du Colombier type = (mcp->setsways >> 25) & MASK(4);
29910dec6bfSDavid du Colombier if (type == 0)
30010dec6bfSDavid du Colombier print("; write-through only");
30110dec6bfSDavid du Colombier else
30210dec6bfSDavid du Colombier print("; write-back type `%s' (%#o) possible",
30310dec6bfSDavid du Colombier wbtype(type), type);
30410dec6bfSDavid du Colombier if (mcp->setsways & (1<<11))
30510dec6bfSDavid du Colombier print("; page table mapping restrictions apply");
30610dec6bfSDavid du Colombier if (mcp->setsways & (1<<2))
30710dec6bfSDavid du Colombier print("; M bit is set in cache type reg");
30810dec6bfSDavid du Colombier print("\n");
30910dec6bfSDavid du Colombier }
31010dec6bfSDavid du Colombier
311b72bcbbfSDavid du Colombier static void
prcachecfg(void)312b72bcbbfSDavid du Colombier prcachecfg(void)
313b72bcbbfSDavid du Colombier {
314b72bcbbfSDavid du Colombier Memcache mc;
315b72bcbbfSDavid du Colombier
31610dec6bfSDavid du Colombier cacheinfo(1, Dcache, &mc);
31710dec6bfSDavid du Colombier prcache(&mc);
31810dec6bfSDavid du Colombier cacheinfo(1, Icache, &mc);
31910dec6bfSDavid du Colombier prcache(&mc);
320b72bcbbfSDavid du Colombier }
321b72bcbbfSDavid du Colombier
322154abd99SDavid du Colombier void
l2cacheon(void)323154abd99SDavid du Colombier l2cacheon(void)
324154abd99SDavid du Colombier {
325b72bcbbfSDavid du Colombier ulong cfg;
32656713243SDavid du Colombier CpucsReg *cpu;
327154abd99SDavid du Colombier L2uncache *l2p;
328154abd99SDavid du Colombier
329154abd99SDavid du Colombier cacheuwbinv();
33080f6c381SDavid du Colombier l2cacheuwbinv();
331b72bcbbfSDavid du Colombier l1cachesoff(); /* turns off L2 as a side effect */
332b72bcbbfSDavid du Colombier
333b72bcbbfSDavid du Colombier cpwrsc(CpDef, CpCLD, 0, 0, 0); /* GL-CPU-100: set D cache lockdown reg. */
334b72bcbbfSDavid du Colombier
335b72bcbbfSDavid du Colombier /* marvell guideline GL-CPU-130 */
3367365b686SDavid du Colombier cpu = (CpucsReg *)soc.cpu;
337b72bcbbfSDavid du Colombier cfg = cpu->cpucfg | L2exists | L2ecc | Cfgiprefetch | Cfgdprefetch;
338b72bcbbfSDavid du Colombier
339b72bcbbfSDavid du Colombier if (L2writeback)
340b72bcbbfSDavid du Colombier cfg &= ~L2writethru; /* see PTE Cached & Buffered bits */
341b72bcbbfSDavid du Colombier else
342b72bcbbfSDavid du Colombier cfg |= L2writethru;
343b72bcbbfSDavid du Colombier cpu->l2cfg = cfg;
344b72bcbbfSDavid du Colombier coherence(); /* force l2 cache to pay attention */
345b72bcbbfSDavid du Colombier cpu->l2tm1 = cpu->l2tm0 = 0x66666666; /* marvell guideline GL-CPU-120 */
346b72bcbbfSDavid du Colombier coherence();
347b72bcbbfSDavid du Colombier
348b72bcbbfSDavid du Colombier cpwrsc(CpL2, CpTESTCFG, CpTCl2waylck, CpTCl2waylock, 0);
349b72bcbbfSDavid du Colombier
350b72bcbbfSDavid du Colombier cachedinv();
35180f6c381SDavid du Colombier l2cacheuinv();
352154abd99SDavid du Colombier
353ffc08dc1SDavid du Colombier /* disable l2 caching of i/o registers */
3547365b686SDavid du Colombier l2p = (L2uncache *)soc.l2cache;
355154abd99SDavid du Colombier memset(l2p, 0, sizeof *l2p);
356fee6e4b8SDavid du Colombier /*
357fee6e4b8SDavid du Colombier * l2: don't cache upper half of address space.
358fee6e4b8SDavid du Colombier * the L2 cache is PIPT, so the addresses are physical.
359fee6e4b8SDavid du Colombier */
360154abd99SDavid du Colombier l2p->win[0].base = 0x80000000 | L2enable; /* 64K multiple */
361b72bcbbfSDavid du Colombier l2p->win[0].size = (32*1024-1) << 16; /* 64K multiples */
362154abd99SDavid du Colombier coherence();
363154abd99SDavid du Colombier
364154abd99SDavid du Colombier l2cachecfgon();
365b72bcbbfSDavid du Colombier l1cacheson(); /* turns L2 on as a side effect */
366fee6e4b8SDavid du Colombier print("l2 cache: 256K or 512K: 4 ways, 32-byte lines, write-%s, sdram only\n",
367b72bcbbfSDavid du Colombier cpu->l2cfg & L2writethru? "through": "back");
368154abd99SDavid du Colombier }
369154abd99SDavid du Colombier
370154abd99SDavid du Colombier /* called late in main */
371154abd99SDavid du Colombier void
archconfinit(void)372154abd99SDavid du Colombier archconfinit(void)
373154abd99SDavid du Colombier {
374df2dbabfSDavid du Colombier m->cpuhz = Frequency;
3757bb09086SDavid du Colombier m->delayloop = m->cpuhz/2000; /* initial estimate */
376ffc08dc1SDavid du Colombier fixaddrmap();
377897ae9c1SDavid du Colombier if (Debug)
378897ae9c1SDavid du Colombier praddrmap();
379b72bcbbfSDavid du Colombier prcachecfg();
380b72bcbbfSDavid du Colombier
381ffc08dc1SDavid du Colombier l2cacheon();
382154abd99SDavid du Colombier }
383154abd99SDavid du Colombier
384154abd99SDavid du Colombier void
archkwlink(void)385154abd99SDavid du Colombier archkwlink(void)
386154abd99SDavid du Colombier {
387154abd99SDavid du Colombier }
388154abd99SDavid du Colombier
389154abd99SDavid du Colombier int
archether(unsigned ctlno,Ether * ether)390c6569576SDavid du Colombier archether(unsigned ctlno, Ether *ether)
391154abd99SDavid du Colombier {
392c6569576SDavid du Colombier if(ctlno >= 2)
393154abd99SDavid du Colombier return -1;
394897ae9c1SDavid du Colombier ether->type = "88e1116";
395154abd99SDavid du Colombier ether->port = ctlno;
396154abd99SDavid du Colombier // ether->mbps = 1000;
397154abd99SDavid du Colombier return 1;
398154abd99SDavid du Colombier }
399154abd99SDavid du Colombier
400154abd99SDavid du Colombier /* LED/USB gpios */
4015e27dea9SDavid du Colombier enum {
4025e27dea9SDavid du Colombier /*
4035e27dea9SDavid du Colombier * the bit assignments are MPP pin numbers from the last page of the
4045e27dea9SDavid du Colombier * sheevaplug 6.0.1 schematic.
4055e27dea9SDavid du Colombier */
4065e27dea9SDavid du Colombier KWOEValHigh = 1<<(49-32), /* pin 49: LED pin */
4075e27dea9SDavid du Colombier KWOEValLow = 1<<29, /* pin 29: USB_PWEN, pin 28: usb_pwerr */
4085e27dea9SDavid du Colombier KWOELow = ~0,
4095e27dea9SDavid du Colombier KWOEHigh = ~0,
410154abd99SDavid du Colombier };
411154abd99SDavid du Colombier
412154abd99SDavid du Colombier /* called early in main */
413154abd99SDavid du Colombier void
archreset(void)414154abd99SDavid du Colombier archreset(void)
415154abd99SDavid du Colombier {
4165e27dea9SDavid du Colombier ulong clocks;
4175e27dea9SDavid du Colombier CpucsReg *cpu;
41856713243SDavid du Colombier Dramctl *dram;
4197365b686SDavid du Colombier GpioReg *gpio;
4205e27dea9SDavid du Colombier
42156713243SDavid du Colombier clockshutdown(); /* watchdog disabled */
422154abd99SDavid du Colombier
423154abd99SDavid du Colombier /* configure gpios */
4247365b686SDavid du Colombier gpio = (GpioReg*)soc.gpio[0];
4257365b686SDavid du Colombier gpio->dataout = KWOEValLow;
426b72bcbbfSDavid du Colombier coherence();
4277365b686SDavid du Colombier gpio->dataoutena = KWOELow;
428154abd99SDavid du Colombier
4297365b686SDavid du Colombier gpio = (GpioReg*)soc.gpio[1];
4307365b686SDavid du Colombier gpio->dataout = KWOEValHigh;
431b72bcbbfSDavid du Colombier coherence();
4327365b686SDavid du Colombier gpio->dataoutena = KWOEHigh;
433154abd99SDavid du Colombier coherence();
434154abd99SDavid du Colombier
4357365b686SDavid du Colombier cpu = (CpucsReg *)soc.cpu;
4365e27dea9SDavid du Colombier cpu->mempm = 0; /* turn everything on */
4375e27dea9SDavid du Colombier coherence();
43856713243SDavid du Colombier
439ab6ce076SDavid du Colombier clocks = MASK(10);
440ab6ce076SDavid du Colombier clocks |= MASK(21) & ~MASK(14);
4415e27dea9SDavid du Colombier clocks &= ~(1<<18 | 1<<1); /* reserved bits */
4425e27dea9SDavid du Colombier cpu->clockgate |= clocks; /* enable all the clocks */
443ffc08dc1SDavid du Colombier cpu->l2cfg |= L2exists; /* when L2exists is 0, the l2 ignores us */
444154abd99SDavid du Colombier coherence();
44556713243SDavid du Colombier
4467365b686SDavid du Colombier dram = (Dramctl *)soc.sdramc;
44756713243SDavid du Colombier dram->ddrctllo &= ~(1<<6); /* marvell guideline GL-MEM-70 */
44856713243SDavid du Colombier
4497365b686SDavid du Colombier *(ulong *)soc.analog = 0x68; /* marvell guideline GL-MISC-40 */
45056713243SDavid du Colombier coherence();
451154abd99SDavid du Colombier }
452154abd99SDavid du Colombier
453154abd99SDavid du Colombier void
archreboot(void)454154abd99SDavid du Colombier archreboot(void)
455154abd99SDavid du Colombier {
4567365b686SDavid du Colombier CpucsReg *cpu;
4577365b686SDavid du Colombier
458154abd99SDavid du Colombier iprint("reset!\n");
459b72bcbbfSDavid du Colombier delay(10);
460154abd99SDavid du Colombier
4617365b686SDavid du Colombier cpu = (CpucsReg *)soc.cpu;
4627365b686SDavid du Colombier cpu->rstout = RstoutSoft;
4637365b686SDavid du Colombier cpu->softreset = ResetSystem;
464b72bcbbfSDavid du Colombier coherence();
4657365b686SDavid du Colombier cpu->cpucsr = Reset;
4665e27dea9SDavid du Colombier coherence();
467154abd99SDavid du Colombier delay(500);
468154abd99SDavid du Colombier
469154abd99SDavid du Colombier splhi();
470154abd99SDavid du Colombier iprint("waiting...");
471154abd99SDavid du Colombier for(;;)
472154abd99SDavid du Colombier idlehands();
473154abd99SDavid du Colombier }
474154abd99SDavid du Colombier
475154abd99SDavid du Colombier void
archconsole(void)476154abd99SDavid du Colombier archconsole(void)
477154abd99SDavid du Colombier {
478154abd99SDavid du Colombier // uartconsole(0, "b115200");
479154abd99SDavid du Colombier //serialputs("uart0 console @ 115200\n", strlen("uart0 console @ 115200\n"));
480154abd99SDavid du Colombier }
481154abd99SDavid du Colombier
482154abd99SDavid du Colombier void
archflashwp(Flash *,int)483154abd99SDavid du Colombier archflashwp(Flash*, int)
484154abd99SDavid du Colombier {
485154abd99SDavid du Colombier }
486154abd99SDavid du Colombier
487897ae9c1SDavid du Colombier int flashat(Flash *f, uintptr pa);
488897ae9c1SDavid du Colombier
489154abd99SDavid du Colombier /*
490154abd99SDavid du Colombier * for ../port/devflash.c:/^flashreset
491154abd99SDavid du Colombier * retrieve flash type, virtual base and length and return 0;
492154abd99SDavid du Colombier * return -1 on error (no flash)
493154abd99SDavid du Colombier */
494154abd99SDavid du Colombier int
archflashreset(int bank,Flash * f)495154abd99SDavid du Colombier archflashreset(int bank, Flash *f)
496154abd99SDavid du Colombier {
497154abd99SDavid du Colombier if(bank != 0)
498154abd99SDavid du Colombier return -1;
499154abd99SDavid du Colombier f->type = "nand";
50006f6463aSDavid du Colombier if (flashat(f, PHYSNAND1))
50106f6463aSDavid du Colombier f->addr = (void*)PHYSNAND1;
50206f6463aSDavid du Colombier else if (flashat(f, PHYSNAND2))
50306f6463aSDavid du Colombier f->addr = (void*)PHYSNAND2;
50406f6463aSDavid du Colombier else
50506f6463aSDavid du Colombier f->addr = nil;
506154abd99SDavid du Colombier f->size = 0; /* done by probe */
507154abd99SDavid du Colombier f->width = 1;
508154abd99SDavid du Colombier f->interleave = 0;
509154abd99SDavid du Colombier return 0;
510154abd99SDavid du Colombier }
511