2 * stuff specific to marvell's kirkwood architecture
3 * as seen in the sheevaplug
6 #include "../port/lib.h"
10 #include "../port/error.h"
13 #include "../port/netif.h"
14 #include "../port/etherif.h"
15 #include "../port/flashif.h"
24 typedef struct GpioReg GpioReg;
36 typedef struct L2uncache L2uncache;
37 typedef struct L2win L2win;
40 ulong base; /* phys addr */
46 /* L2win->base bits */
50 typedef struct Dramctl Dramctl;
88 typedef struct SDramdReg SDramdReg;
96 typedef struct Addrmap Addrmap;
97 typedef struct Addrwin Addrwin;
100 ulong ctl; /* see Winenable in io.h */
105 ulong dirba; /* device internal reg's base addr.: PHYSIO */
109 .cpu = PHYSIO+0x20100,
110 .devid = PHYSIO+0x10034,
111 .l2cache = PHYSIO+0x20a00, /* uncachable addrs for L2 */
112 .sdramc = PHYSIO+0x01400,
113 // .sdramd = PHYSIO+0x01500, /* unused */
115 .iocfg = PHYSIO+0x100e0,
116 .addrmap = PHYSIO+0x20000,
117 .intr = PHYSIO+0x20200,
118 .nand = PHYSIO+0x10418,
119 .cesa = PHYSIO+0x30000, /* crypto accelerator */
120 .ehci = PHYSIO+0x50000,
121 .spi = PHYSIO+0x10600,
122 .twsi = PHYSIO+0x11000,
124 .analog = PHYSIO+0x1007c,
125 .pci = PHYSIO+0x40000,
126 .pcibase = PHYSIO+0x41800,
128 .rtc = PHYSIO+0x10300,
129 .clock = PHYSIO+0x20300,
130 // .clockctl = PHYSIO+0x1004c, /* unused */
132 .ether = { PHYSIO+0x72000, PHYSIO+0x76000, },
133 .sata = { PHYSIO+0x80000, /* sata config reg here */
134 PHYSIO+0x82000, /* edma config reg here */
135 PHYSIO+0x84000, /* edma config reg here */
137 .uart = { PHYSIO+0x12000, PHYSIO+0x12100, },
138 .gpio = { PHYSIO+0x10100, PHYSIO+0x10140, },
142 * sheeva/openrd u-boot leaves us with this address map:
144 * 0 targ 4 attr 0xe8 size 256MB addr 0x9:: remap addr 0x9:: pci mem
145 * 1 targ 1 attr 0x2f size 8MB addr 0xf9:: remap addr 0xf9:: nand flash
146 * 2 targ 4 attr 0xe0 size 16MB addr 0xf:: remap addr 0xc:: pci i/o
147 * 3 targ 1 attr 0x1e size 16MB addr 0xf8:: remap addr 0x0 spi flash
148 * 4 targ 1 attr 0x1d size 16MB addr 0xff:: boot rom
149 * 5 targ 1 attr 0x1e size 128MB addr 0xe8:: disabled spi flash
150 * 6 targ 1 attr 0x1d size 128MB addr 0xf:: disabled boot rom
151 * 7 targ 3 attr 0x1 size 64K addr 0xfb:: crypto sram
153 #define WINTARG(ctl) (((ctl) >> 4) & 017)
154 #define WINATTR(ctl) (((ctl) >> 8) & 0377)
155 #define WIN64KSIZE(ctl) (((ctl) >> 16) + 1)
158 praddrwin(Addrwin *win, int i)
160 ulong ctl, targ, attr, size64k;
169 size64k = WIN64KSIZE(ctl);
170 print("cpu addr map: %s window %d: targ %ld attr %#lux size %,ld addr %#lux",
171 ctl & Winenable? "enabled": "disabled", i, targ, attr,
172 size64k * 64*1024, win->base);
174 print(" remap addr %#llux", (uvlong)win->remaphi<<32 |
183 ulong ctl, targ, attr, size64k;
187 map = (Addrmap *)soc.addrmap;
188 for (i = 0; i < nelem(map->win); i++) {
193 size64k = WIN64KSIZE(ctl);
196 if (targ == Targcesasram) {
197 win->ctl |= Winenable;
198 win->base = PHYSCESASRAM;
203 if (map->dirba != PHYSIO)
204 panic("dirba not %#ux", PHYSIO);
213 map = (Addrmap *)soc.addrmap;
214 for (i = 0; i < nelem(map->win); i++)
215 praddrwin(&map->win[i], i);
221 /* see Hacker's Delight if this isn't obvious */
222 return (ul & (ul - 1)) == 0;
226 * return exponent of smallest power of 2 ≥ n
234 if (!ispow2(n) || n == 0)
240 cacheinfo(int level, int kind, Memcache *cp) /* l1 only */
242 uint len, assoc, size;
245 /* get cache types & sizes (read-only reg) */
246 setsways = cprdsc(0, CpID, CpIDidct, CpIDct);
251 if ((setsways & (1<<24)) == 0)
256 assoc = (setsways >> 3) & MASK(3);
257 cp->nways = 1 << assoc;
258 size = (setsways >> 6) & MASK(4);
259 cp->size = 1 << (size + 9);
260 len = setsways & MASK(2);
261 cp->log2linelen = len + 3;
262 cp->linelen = 1 << cp->log2linelen;
263 cp->setsways = setsways;
265 cp->nsets = 1 << (size + 6 - assoc - len);
266 cp->setsh = cp->log2linelen;
267 cp->waysh = 32 - log2(cp->nways);
273 static char *types[] = {
276 "reg 7 ops, no lock-down",
277 [06] "reg 7 ops, format A",
278 [07] "reg 7 ops, format B deprecated",
279 [016] "reg 7 ops, format C",
280 [05] "reg 7 ops, format D",
283 if (type >= nelem(types) || types[type] == nil)
289 prcache(Memcache *mcp)
294 if (mcp->kind == Unified)
296 else if (mcp->kind == Icache)
298 else if (mcp->kind == Dcache)
302 print("l%d %c: %d bytes, %d ways %d sets %d bytes/line",
303 mcp->level, id, mcp->size, mcp->nways, mcp->nsets,
305 if (mcp->linelen != CACHELINESZ)
306 print(" *should* be %d", CACHELINESZ);
307 type = (mcp->setsways >> 25) & MASK(4);
309 print("; write-through only");
311 print("; write-back type `%s' (%#o) possible",
313 if (mcp->setsways & (1<<11))
314 print("; page table mapping restrictions apply");
315 if (mcp->setsways & (1<<2))
316 print("; M bit is set in cache type reg");
325 cacheinfo(1, Dcache, &mc);
327 cacheinfo(1, Icache, &mc);
340 l1cachesoff(); /* turns off L2 as a side effect */
342 cpwrsc(CpDef, CpCLD, 0, 0, 0); /* GL-CPU-100: set D cache lockdown reg. */
344 /* marvell guideline GL-CPU-130 */
345 cpu = (CpucsReg *)soc.cpu;
346 cfg = cpu->cpucfg | L2exists | L2ecc | Cfgiprefetch | Cfgdprefetch;
349 cfg &= ~L2writethru; /* see PTE Cached & Buffered bits */
353 coherence(); /* force l2 cache to pay attention */
354 cpu->l2tm1 = cpu->l2tm0 = 0x66666666; /* marvell guideline GL-CPU-120 */
357 cpwrsc(CpL2, CpTESTCFG, CpTCl2waylck, CpTCl2waylock, 0);
362 /* disable l2 caching of i/o registers */
363 l2p = (L2uncache *)soc.l2cache;
364 memset(l2p, 0, sizeof *l2p);
366 * l2: don't cache upper half of address space.
367 * the L2 cache is PIPT, so the addresses are physical.
369 l2p->win[0].base = 0x80000000 | L2enable; /* 64K multiple */
370 l2p->win[0].size = (32*1024-1) << 16; /* 64K multiples */
374 l1cacheson(); /* turns L2 on as a side effect */
375 print("l2 cache: 256K or 512K: 4 ways, 32-byte lines, write-%s, sdram only\n",
376 cpu->l2cfg & L2writethru? "through": "back");
379 /* called late in main */
383 m->cpuhz = Frequency;
384 m->delayloop = m->cpuhz/2000; /* initial estimate */
401 * the bit assignments are MPP pin numbers from the last page of the
402 * sheevaplug 6.0.1 schematic.
404 KWOEValHigh = 1<<(49-32), /* pin 49: LED pin */
405 KWOEValLow = 1<<29, /* pin 29: USB_PWEN, pin 28: usb_pwerr */
410 /* called early in main */
419 clockshutdown(); /* watchdog disabled */
421 /* configure gpios */
422 gpio = (GpioReg*)soc.gpio[0];
423 gpio->dataout = KWOEValLow;
425 gpio->dataoutena = KWOELow;
427 gpio = (GpioReg*)soc.gpio[1];
428 gpio->dataout = KWOEValHigh;
430 gpio->dataoutena = KWOEHigh;
433 cpu = (CpucsReg *)soc.cpu;
434 cpu->mempm = 0; /* turn everything on */
438 clocks |= MASK(21) & ~MASK(14);
439 clocks &= ~(1<<18 | 1<<1); /* reserved bits */
440 cpu->clockgate |= clocks; /* enable all the clocks */
441 cpu->l2cfg |= L2exists; /* when L2exists is 0, the l2 ignores us */
444 dram = (Dramctl *)soc.sdramc;
445 dram->ddrctllo &= ~(1<<6); /* marvell guideline GL-MEM-70 */
447 *(ulong *)soc.analog = 0x68; /* marvell guideline GL-MISC-40 */
459 cpu = (CpucsReg *)soc.cpu;
460 cpu->rstout = RstoutSoft;
461 cpu->softreset = ResetSystem;
468 iprint("waiting...");
476 // uartconsole(0, "b115200");
477 //serialputs("uart0 console @ 115200\n", strlen("uart0 console @ 115200\n"));
481 archflashwp(Flash*, int)
485 int flashat(Flash *f, uintptr pa);
488 * for ../port/devflash.c:/^flashreset
489 * retrieve flash type, virtual base and length and return 0;
490 * return -1 on error (no flash)
493 archflashreset(int bank, Flash *f)
498 if (flashat(f, PHYSNAND1))
499 f->addr = (void*)PHYSNAND1;
500 else if (flashat(f, PHYSNAND2))
501 f->addr = (void*)PHYSNAND2;
504 f->size = 0; /* done by probe */