1 /*
2 * omap3530 SoC (e.g. beagleboard) architecture-specific stuff
3 *
4 * errata: usb port 3 cannot operate in ulpi mode, only serial or
5 * utmi tll mode
6 */
7
8 #include "u.h"
9 #include "../port/lib.h"
10 #include "mem.h"
11 #include "dat.h"
12 #include "fns.h"
13 #include "../port/error.h"
14 #include "io.h"
15 #include "arm.h"
16
17 #include "../port/netif.h"
18 #include "etherif.h"
19 #include "../port/flashif.h"
20 #include "../port/usb.h"
21 #include "../port/portusbehci.h"
22 #include "usbehci.h"
23
24 #define FREQSEL(x) ((x) << 4)
25
26 typedef struct Cm Cm;
27 typedef struct Cntrl Cntrl;
28 typedef struct Gen Gen;
29 typedef struct Gpio Gpio;
30 typedef struct L3agent L3agent;
31 typedef struct L3protreg L3protreg;
32 typedef struct L3regs L3regs;
33 typedef struct Prm Prm;
34 typedef struct Usbotg Usbotg;
35 typedef struct Usbtll Usbtll;
36
37 /* omap3 non-standard usb stuff */
38 struct Usbotg {
39 uchar faddr;
40 uchar power;
41 ushort intrtx;
42 ushort intrrx;
43 ushort intrtxe;
44 ushort intrrxe;
45 uchar intrusb;
46 uchar intrusbe;
47 ushort frame;
48 uchar index;
49 uchar testmode;
50
51 /* indexed registers follow; ignore for now */
52 uchar _pad0[0x400 - 0x10];
53
54 ulong otgrev;
55 ulong otgsyscfg;
56 ulong otgsyssts;
57 ulong otgifcsel; /* interface selection */
58 uchar _pad1[0x414 - 0x410];
59 ulong otgforcestdby;
60 };
61
62 enum {
63 /* power bits */
64 Hsen = 1<<5, /* high-speed enable */
65
66 /* testmode bits */
67 Forcehost = 1<<7, /* force host (vs peripheral) mode */
68 Forcehs = 1<<4, /* force high-speed at reset */
69
70 /* otgsyscfg bits */
71 Midle = 1<<12, /* no standby mode */
72 Sidle = 1<<3, /* no idle mode */
73 // Softreset = 1<<1,
74
75 /* otgsyssts bits, per sysstatus */
76 };
77
78 struct Usbtll {
79 ulong revision; /* ro */
80 uchar _pad0[0x10-0x4];
81 ulong sysconfig;
82 ulong sysstatus; /* ro */
83
84 ulong irqstatus;
85 ulong irqenable;
86 };
87
88 enum {
89 /* sysconfig bits */
90 Softreset = 1<<1,
91
92 /* sysstatus bits */
93 Resetdone = 1<<0,
94 /* only in uhh->sysstatus */
95 Ehci_resetdone = 1<<2,
96 Ohci_resetdone = 1<<1,
97 };
98
99 /*
100 * an array of these structs is preceded by error_log at 0x20, control,
101 * error_clear_single, error_clear_multi. first struct is at offset 0x48.
102 */
103 struct L3protreg { /* hw: an L3 protection region */
104 uvlong req_info_perm;
105 uvlong read_perm;
106 uvlong write_perm;
107 uvlong addr_match; /* ro? write this one last, then flush */
108 };
109
110 // TODO: set these permission bits (e.g., for usb)?
111 enum {
112 Permusbhost = 1<<9,
113 Permusbotg = 1<<4,
114 Permsysdma = 1<<3,
115 Permmpu = 1<<1,
116 };
117
118 struct L3agent { /* hw registers */
119 uchar _pad0[0x20];
120 uvlong ctl;
121 uvlong sts;
122 uchar _pad1[0x58 - 0x30];
123 uvlong errlog;
124 uvlong errlogaddr;
125 };
126
127 struct L3regs {
128 L3protreg *base; /* base of array */
129 int upper; /* index maximum */
130 char *name;
131 };
132 L3regs l3regs[] = {
133 (L3protreg *)(PHYSL3GPMCPM+0x48), 7, "gpmc", /* known to be first */
134 (L3protreg *)(PHYSL3PMRT+0x48), 1, "rt", /* l3 config */
135 (L3protreg *)(PHYSL3OCTRAM+0x48), 7, "ocm ram",
136 (L3protreg *)(PHYSL3OCTROM+0x48), 1, "ocm rom",
137 (L3protreg *)(PHYSL3MAD2D+0x48), 7, "mad2d", /* die-to-die */
138 (L3protreg *)(PHYSL3IVA+0x48), 3, "iva2.2", /* a/v */
139 };
140
141 /*
142 * PRM_CLKSEL (0x48306d40) low 3 bits are system clock speed, assuming
143 * units of MHz: 0 = 12, 1 = 13, 2 = 19.2, 3 = 26, 4 = 38.4, 5 = 16.8
144 */
145
146 struct Cm { /* clock management */
147 ulong fclken; /* ``functional'' clock enable */
148 ulong fclken2;
149 ulong fclken3;
150 uchar _pad0[0x10 - 0xc];
151
152 ulong iclken; /* ``interface'' clock enable */
153 ulong iclken2;
154 ulong iclken3;
155 uchar _pad1[0x20 - 0x1c];
156
157 ulong idlest; /* idle status */
158 ulong idlest2;
159 ulong idlest3;
160 uchar _pad2[0x30 - 0x2c];
161
162 ulong autoidle;
163 ulong autoidle2;
164 ulong autoidle3;
165 uchar _pad3[0x40 - 0x3c];
166
167 union {
168 ulong clksel[5];
169 struct unused {
170 ulong sleepdep;
171 ulong clkstctrl;
172 ulong clkstst;
173 };
174 uchar _pad4[0x70 - 0x40];
175 };
176 ulong clkoutctrl;
177 };
178
179 struct Prm { /* power & reset management */
180 uchar _pad[0x50];
181 ulong rstctrl;
182 };
183
184 struct Gpio {
185 ulong _pad0[4];
186 ulong sysconfig;
187 ulong sysstatus;
188
189 ulong irqsts1; /* for mpu */
190 ulong irqen1;
191 ulong wkupen;
192 ulong _pad1;
193 ulong irqsts2; /* for iva */
194 ulong irqen2;
195
196 ulong ctrl;
197
198 ulong oe;
199 ulong datain;
200 ulong dataout;
201
202 ulong lvldet0;
203 ulong lvldet1;
204 ulong risingdet;
205 ulong fallingdet;
206
207 /* rest are uninteresting */
208 ulong deben; /* debouncing enable */
209 ulong debtime;
210 ulong _pad2[2];
211
212 ulong clrirqen1;
213 ulong setirqen1;
214 ulong _pad3[2];
215
216 ulong clrirqen2;
217 ulong setirqen2;
218 ulong _pad4[2];
219
220 ulong clrwkupen;
221 ulong setwkupen;
222 ulong _pad5[2];
223
224 ulong clrdataout;
225 ulong setdataout;
226 };
227
228 enum {
229 /* clock enable & idle status bits */
230 Wkusimocp = 1 << 9, /* SIM card: uses 120MHz clock */
231 Wkwdt2 = 1 << 5, /* wdt2 clock enable bit for wakeup */
232 Wkgpio1 = 1 << 3, /* gpio1 " */
233 Wkgpt1 = 1 << 0, /* gpt1 " */
234
235 Dssl3l4 = 1 << 0, /* dss l3, l4 i clks */
236 Dsstv = 1 << 2, /* dss tv f clock */
237 Dss2 = 1 << 1, /* dss clock 2 */
238 Dss1 = 1 << 0, /* dss clock 1 */
239
240 Pergpio6 = 1 << 17,
241 Pergpio5 = 1 << 16,
242 Pergpio4 = 1 << 15,
243 Pergpio3 = 1 << 14,
244 Pergpio2 = 1 << 13,
245 Perwdt3 = 1 << 12, /* wdt3 clock enable bit for periphs */
246 Peruart3 = 1 << 11, /* console uart */
247 Pergpt9 = 1 << 10,
248 Pergpt8 = 1 << 9,
249 Pergpt7 = 1 << 8,
250 Pergpt6 = 1 << 7,
251 Pergpt5 = 1 << 6,
252 Pergpt4 = 1 << 5,
253 Pergpt3 = 1 << 4,
254 Pergpt2 = 1 << 3, /* gpt2 clock enable bit for periphs */
255
256 Perenable = Pergpio6 | Pergpio5 | Perwdt3 | Pergpt2 | Peruart3,
257
258 Usbhost2 = 1 << 1, /* 120MHz clock enable */
259 Usbhost1 = 1 << 0, /* 48MHz clock enable */
260 Usbhost = Usbhost1, /* iclock enable */
261 Usbhostidle = 1 << 1,
262 Usbhoststdby = 1 << 0,
263
264 Coreusbhsotg = 1 << 4, /* usb hs otg enable bit */
265 Core3usbtll = 1 << 2, /* usb tll enable bit */
266
267 /* core->idlest bits */
268 Coreusbhsotgidle = 1 << 5,
269 Coreusbhsotgstdby= 1 << 4,
270
271 Dplllock = 7,
272
273 /* mpu->idlest2 bits */
274 Dplllocked = 1,
275 Dpllbypassed = 0,
276
277 /* wkup->idlest bits */
278 Gpio1idle = 1 << 3,
279
280 /* dss->idlest bits */
281 Dssidle = 1 << 1,
282
283 Gpio1vidmagic = 1<<24 | 1<<8 | 1<<5, /* gpio 1 pins for video */
284 };
285 enum {
286 Rstgs = 1 << 1, /* global sw. reset */
287
288 /* fp control regs. most are read-only */
289 Fpsid = 0,
290 Fpscr, /* rw */
291 Mvfr1 = 6,
292 Mvfr0,
293 Fpexc, /* rw */
294 };
295
296 /* see ether9221.c for explanation */
297 enum {
298 Ethergpio = 176,
299 Etherchanbit = 1 << (Ethergpio % 32),
300 };
301
302 /*
303 * these shift values are for the Cortex-A8 L1 cache (A=2, L=6) and
304 * the Cortex-A8 L2 cache (A=3, L=6).
305 * A = log2(# of ways), L = log2(bytes per cache line).
306 * see armv7 arch ref p. 1403.
307 *
308 * #define L1WAYSH 30
309 * #define L1SETSH 6
310 * #define L2WAYSH 29
311 * #define L2SETSH 6
312 */
313 enum {
314 /*
315 * cache capabilities. write-back vs write-through is controlled
316 * by the Buffered bit in PTEs.
317 */
318 Cawt = 1 << 31,
319 Cawb = 1 << 30,
320 Cara = 1 << 29,
321 Cawa = 1 << 28,
322 };
323
324 struct Gen {
325 ulong padconf_off;
326 ulong devconf0;
327 uchar _pad0[0x68 - 8];
328 ulong devconf1;
329 };
330
331 struct Cntrl {
332 ulong _pad0;
333 ulong id;
334 ulong _pad1;
335 ulong skuid;
336 };
337
338
339 static char *
devidstr(ulong)340 devidstr(ulong)
341 {
342 return "ARM Cortex-A8";
343 }
344
345 void
archomaplink(void)346 archomaplink(void)
347 {
348 }
349
350 void
archconfinit(void)351 archconfinit(void)
352 {
353 char *p;
354 ulong mhz;
355
356 assert(m != nil);
357 m->cpuhz = 500 * Mhz; /* beagle speed */
358 p = getconf("*cpumhz");
359 if (p) {
360 mhz = atoi(p) * Mhz;
361 if (mhz >= 100*Mhz && mhz <= 3000UL*Mhz)
362 m->cpuhz = mhz;
363 }
364 m->delayloop = m->cpuhz/2000; /* initial estimate */
365 }
366
367 static void
prperm(uvlong perm)368 prperm(uvlong perm)
369 {
370 if (perm == MASK(16))
371 print("all");
372 else
373 print("%#llux", perm);
374 }
375
376 static void
prl3region(L3protreg * pr,int r)377 prl3region(L3protreg *pr, int r)
378 {
379 int level, size, addrspace;
380 uvlong am, base;
381
382 if (r == 0)
383 am = 0;
384 else
385 am = pr->addr_match;
386 size = (am >> 3) & MASK(5);
387 if (r > 0 && size == 0) /* disabled? */
388 return;
389
390 print(" %d: perms req ", r);
391 prperm(pr->req_info_perm);
392 if (pr->read_perm == pr->write_perm && pr->read_perm == MASK(16))
393 print(" rw all");
394 else {
395 print(" read ");
396 prperm(pr->read_perm);
397 print(" write ");
398 prperm(pr->write_perm);
399 }
400 if (r == 0)
401 print(", all addrs level 0");
402 else {
403 size = 1 << size; /* 2^size */
404 level = (am >> 9) & 1;
405 if (r == 1)
406 level = 3;
407 else
408 level++;
409 addrspace = am & 7;
410 base = am & ~MASK(10);
411 print(", base %#llux size %dKB level %d addrspace %d",
412 base, size, level, addrspace);
413 }
414 print("\n");
415 delay(100);
416 }
417
418
419 /*
420 * dump the l3 interconnect firewall settings by protection region.
421 * mpu, sys dma and both usbs (0x21a) should be set in all read & write
422 * permission registers.
423 */
424 static void
dumpl3pr(void)425 dumpl3pr(void)
426 {
427 int r;
428 L3regs *reg;
429 L3protreg *pr;
430
431 for (reg = l3regs; reg < l3regs + nelem(l3regs); reg++) {
432 print("%#p (%s) enabled l3 regions:\n", reg->base, reg->name);
433 for (r = 0; r <= reg->upper; r++)
434 prl3region(reg->base + r, r);
435 }
436 if (0) { // TODO
437 /* touch up gpmc perms */
438 reg = l3regs; /* first entry is gpmc */
439 for (r = 0; r <= reg->upper; r++) {
440 pr = reg->base + r;
441 // TODO
442 }
443 print("%#p (%s) modified l3 regions:\n", reg->base, reg->name);
444 for (r = 0; r <= reg->upper; r++)
445 prl3region(reg->base + r, r);
446 }
447 }
448
449 static void
p16(uchar * p,ulong v)450 p16(uchar *p, ulong v)
451 {
452 *p++ = v>>8;
453 *p = v;
454 }
455
456 static void
p32(uchar * p,ulong v)457 p32(uchar *p, ulong v)
458 {
459 *p++ = v>>24;
460 *p++ = v>>16;
461 *p++ = v>>8;
462 *p = v;
463 }
464
465 int
archether(unsigned ctlrno,Ether * ether)466 archether(unsigned ctlrno, Ether *ether)
467 {
468 switch(ctlrno) {
469 case 0:
470 /* there's no built-in ether on the beagle but igepv2 has 1 */
471 ether->type = "9221";
472 ether->ctlrno = ctlrno;
473 ether->irq = 34;
474 ether->nopt = 0;
475 ether->mbps = 100;
476 return 1;
477 }
478 return -1;
479 }
480
481 /*
482 * turn on all the necessary clocks on the SoC.
483 *
484 * a ``functional'' clock drives a device; an ``interface'' clock drives
485 * its communication with the rest of the system. so the interface
486 * clock must be enabled to reach the device's registers.
487 *
488 * dplls: 1 mpu, 2 iva2, 3 core, 4 per, 5 per2.
489 */
490
491 static void
configmpu(void)492 configmpu(void)
493 {
494 ulong clk, mhz, nmhz, maxmhz;
495 Cm *mpu = (Cm *)PHYSSCMMPU;
496 Cntrl *id = (Cntrl *)PHYSCNTRL;
497
498 if ((id->skuid & MASK(4)) == 8)
499 maxmhz = 720;
500 else
501 maxmhz = 600;
502 iprint("cpu capable of %ldMHz operation", maxmhz);
503
504 clk = mpu->clksel[0];
505 mhz = (clk >> 8) & MASK(11); /* configured speed */
506 // iprint("\tfclk src %ld; dpll1 mult %ld (MHz) div %ld",
507 // (clk >> 19) & MASK(3), mhz, clk & MASK(7));
508 iprint("; at %ldMHz", mhz);
509 nmhz = m->cpuhz / Mhz; /* nominal speed */
510 if (mhz == nmhz) {
511 iprint("\n");
512 return;
513 }
514
515 mhz = nmhz;
516 if (mhz > maxmhz) {
517 mhz = maxmhz;
518 iprint("; limiting operation to %ldMHz", mhz);
519 }
520
521 /* disable dpll1 lock mode; put into low-power bypass mode */
522 mpu->fclken2 = mpu->fclken2 & ~MASK(3) | 5;
523 coherence();
524 while (mpu->idlest2 != Dpllbypassed)
525 ;
526
527 /*
528 * there's a dance to change processor speed,
529 * prescribed in spruf98d §4.7.6.9.
530 */
531
532 /* just change multiplier; leave divider alone at 12 (meaning 13?) */
533 mpu->clksel[0] = clk & ~(MASK(11) << 8) | mhz << 8;
534 coherence();
535
536 /* set output divider (M2) in clksel[1]: leave at 1 */
537
538 /*
539 * u-boot calls us with just freqsel 3 (~1MHz) & dpll1 lock mode.
540 */
541 /* set FREQSEL */
542 mpu->fclken2 = mpu->fclken2 & ~FREQSEL(MASK(4)) | FREQSEL(3);
543 coherence();
544
545 /* set ramp-up delay to `fast' */
546 mpu->fclken2 = mpu->fclken2 & ~(MASK(2) << 8) | 3 << 8;
547 coherence();
548
549 /* set auto-recalibration (off) */
550 mpu->fclken2 &= ~(1 << 3);
551 coherence();
552
553 /* disable auto-idle: ? */
554 /* unmask clock intr: later */
555
556 /* enable dpll lock mode */
557 mpu->fclken2 |= Dplllock;
558 coherence();
559 while (mpu->idlest2 != Dplllocked)
560 ;
561 delay(200); /* allow time for speed to ramp up */
562
563 if (((mpu->clksel[0] >> 8) & MASK(11)) != mhz)
564 panic("mpu clock speed change didn't stick");
565 iprint("; now at %ldMHz\n", mhz);
566 }
567
568 static void
configpll(void)569 configpll(void)
570 {
571 int i;
572 Cm *pll = (Cm *)PHYSSCMPLL;
573
574 pll->clkoutctrl |= 1 << 7; /* enable sys_clkout2 */
575 coherence();
576 delay(10);
577
578 /*
579 * u-boot calls us with just freqsel 3 (~1MHz) & lock mode
580 * for both dplls (3 & 4). ensure that.
581 */
582 if ((pll->idlest & 3) != 3) {
583 /* put dpll[34] into low-power bypass mode */
584 pll->fclken = pll->fclken & ~(MASK(3) << 16 | MASK(3)) |
585 1 << 16 | 5;
586 coherence();
587 while (pll->idlest & 3) /* wait for both to bypass or stop */
588 ;
589
590 pll->fclken = (FREQSEL(3) | Dplllock) << 16 |
591 FREQSEL(3) | Dplllock;
592 coherence();
593 while ((pll->idlest & 3) != 3) /* wait for both to lock */
594 ;
595 }
596
597 /*
598 * u-boot calls us with just freqsel 1 (default but undefined)
599 * & stop mode for dpll5. try to lock it at 120MHz.
600 */
601 if (!(pll->idlest2 & Dplllocked)) {
602 /* force dpll5 into low-power bypass mode */
603 pll->fclken2 = 3 << 8 | FREQSEL(1) | 1;
604 coherence();
605 for (i = 0; pll->idlest2 & Dplllocked && i < 20; i++)
606 delay(50);
607 if (i >= 20)
608 iprint(" [dpll5 failed to stop]");
609
610 /*
611 * CORE_CLK is 26MHz.
612 */
613 pll->clksel[4-1] = 120 << 8 | 12; /* M=120, N=12+1 */
614 /* M2 divisor: 120MHz clock is exactly the DPLL5 clock */
615 pll->clksel[5-1] = 1;
616 coherence();
617
618 pll->fclken2 = 3 << 8 | FREQSEL(1) | Dplllock; /* def. freq */
619 coherence();
620
621 for (i = 0; !(pll->idlest2 & Dplllocked) && i < 20; i++)
622 delay(50);
623 if (i >= 20)
624 iprint(" [dpll5 failed to lock]");
625 }
626 if (!(pll->idlest2 & (1<<1)))
627 iprint(" [no 120MHz clock]");
628 if (!(pll->idlest2 & (1<<3)))
629 iprint(" [no dpll5 120MHz clock output]");
630 }
631
632 static void
configper(void)633 configper(void)
634 {
635 Cm *per = (Cm *)PHYSSCMPER;
636
637 per->clksel[0] &= ~MASK(8); /* select 32kHz clock for GPTIMER2-9 */
638
639 per->iclken |= Perenable;
640 coherence();
641 per->fclken |= Perenable;
642 coherence();
643 while (per->idlest & Perenable)
644 ;
645
646 per->autoidle = 0;
647 coherence();
648 }
649
650 static void
configwkup(void)651 configwkup(void)
652 {
653 Cm *wkup = (Cm *)PHYSSCMWKUP;
654
655 /* select 32kHz clock (not system clock) for GPTIMER1 */
656 wkup->clksel[0] &= ~1;
657
658 wkup->iclken |= Wkusimocp | Wkwdt2 | Wkgpt1;
659 coherence();
660 wkup->fclken |= Wkusimocp | Wkwdt2 | Wkgpt1;
661 coherence();
662 while (wkup->idlest & (Wkusimocp | Wkwdt2 | Wkgpt1))
663 ;
664 }
665
666 static void
configusb(void)667 configusb(void)
668 {
669 int i;
670 Cm *usb = (Cm *)PHYSSCMUSB;
671
672 /*
673 * make the usb registers accessible without address faults,
674 * notably uhh, ochi & ehci. tll seems to be separate & otg is okay.
675 */
676 usb->iclken |= Usbhost;
677 coherence();
678 usb->fclken |= Usbhost1 | Usbhost2; /* includes 120MHz clock */
679 coherence();
680 for (i = 0; usb->idlest & Usbhostidle && i < 20; i++)
681 delay(50);
682 if (i >= 20)
683 iprint(" [usb inaccessible]");
684 }
685
686 static void
configcore(void)687 configcore(void)
688 {
689 Cm *core = (Cm *)PHYSSCMCORE;
690
691 /*
692 * make the usb tll registers accessible.
693 */
694 core->iclken |= Coreusbhsotg;
695 core->iclken3 |= Core3usbtll;
696 coherence();
697 core->fclken3 |= Core3usbtll;
698 coherence();
699 delay(100);
700 while (core->idlest & Coreusbhsotgidle)
701 ;
702 if (core->idlest3 & Core3usbtll)
703 iprint(" [no usb tll]");
704 }
705
706 static void
configclks(void)707 configclks(void)
708 {
709 int s;
710 Gen *gen = (Gen *)PHYSSCMPCONF;
711
712 delay(20);
713 s = splhi();
714 configmpu(); /* sets cpu clock rate, turns on dplls 1 & 2 */
715
716 /*
717 * the main goal is to get enough clocks running, in the right order,
718 * so that usb has all the necessary clock signals.
719 */
720 iprint("clocks:");
721 iprint(" usb");
722 configusb(); /* starts usb clocks & 120MHz clock */
723 iprint(", pll");
724 configpll(); /* starts dplls 3, 4 & 5 & 120MHz clock */
725 iprint(", wakeup");
726 configwkup(); /* starts timer clocks and usim clock */
727 iprint(", per");
728 configper(); /* starts timer & gpio (ether) clocks */
729 iprint(", core");
730 configcore(); /* starts usb tll */
731 iprint("\n");
732
733 gen->devconf0 |= 1 << 1 | 1 << 0; /* dmareq[01] edge sensitive */
734 /* make dmareq[2-6] edge sensitive */
735 gen->devconf1 |= 1 << 23 | 1 << 22 | 1 << 21 | 1 << 8 | 1 << 7;
736 coherence();
737 splx(s);
738 delay(20);
739 }
740
741 static void
resetwait(ulong * reg)742 resetwait(ulong *reg)
743 {
744 long bound;
745
746 for (bound = 400*Mhz; !(*reg & Resetdone) && bound > 0; bound--)
747 ;
748 if (bound <= 0)
749 iprint("archomap: Resetdone didn't come ready\n");
750 }
751
752 /*
753 * gpio irq 1 goes to the mpu intr ctlr; irq 2 goes to the iva's.
754 * this stuff is magic and without it, we won't get irq 34 interrupts
755 * from the 9221 ethernet controller.
756 */
757 static void
configgpio(void)758 configgpio(void)
759 {
760 Gpio *gpio = (Gpio *)PHYSGPIO6;
761
762 gpio->sysconfig = Softreset;
763 coherence();
764 resetwait(&gpio->sysstatus);
765
766 gpio->ctrl = 1<<1 | 0; /* enable this gpio module, gating ratio 1 */
767 gpio->oe |= Etherchanbit; /* cfg ether pin as input */
768 coherence();
769
770 gpio->irqen1 = Etherchanbit; /* channel # == pin # */
771 gpio->irqen2 = 0;
772
773 gpio->lvldet0 = Etherchanbit; /* enable irq ass'n on low det'n */
774 gpio->lvldet1 = 0; /* disable irq ass'n on high det'n */
775 gpio->risingdet = 0; /* enable irq rising edge det'n */
776 gpio->fallingdet = 0; /* disable irq falling edge det'n */
777
778 gpio->wkupen = 0;
779
780 gpio->deben = 0; /* no de-bouncing */
781 gpio->debtime = 0;
782 coherence();
783
784 gpio->irqsts1 = ~0; /* dismiss all outstanding intrs */
785 gpio->irqsts2 = ~0;
786 coherence();
787 }
788
789 void
configscreengpio(void)790 configscreengpio(void)
791 {
792 Cm *wkup = (Cm *)PHYSSCMWKUP;
793 Gpio *gpio = (Gpio *)PHYSGPIO1;
794
795 /* no clocksel needed */
796 wkup->iclken |= Wkgpio1;
797 coherence();
798 wkup->fclken |= Wkgpio1; /* turn gpio clock on */
799 coherence();
800 // wkup->autoidle |= Wkgpio1; /* set gpio clock on auto */
801 wkup->autoidle = 0;
802 coherence();
803 while (wkup->idlest & Gpio1idle)
804 ;
805
806 /*
807 * 0 bits in oe are output signals.
808 * enable output for gpio 1 (first gpio) video magic pins.
809 */
810 gpio->oe &= ~Gpio1vidmagic;
811 coherence();
812 gpio->dataout |= Gpio1vidmagic; /* set output pins to 1 */
813 coherence();
814 delay(50);
815 }
816
817 void
screenclockson(void)818 screenclockson(void)
819 {
820 Cm *dss = (Cm *)PHYSSCMDSS;
821
822 dss->iclken |= Dssl3l4;
823 coherence();
824 dss->fclken = Dsstv | Dss2 | Dss1;
825 coherence();
826 /* tv fclk is dpll4 clk; dpll4 m4 divide factor for dss1 fclk is 2 */
827 dss->clksel[0] = 1<<12 | 2;
828 coherence();
829 delay(50);
830 while (dss->idlest & Dssidle)
831 ;
832 }
833
834 void
gpioirqclr(void)835 gpioirqclr(void)
836 {
837 Gpio *gpio = (Gpio *)PHYSGPIO6;
838
839 gpio->irqsts1 = gpio->irqsts1;
840 coherence();
841 }
842
843 static char *
l1iptype(uint type)844 l1iptype(uint type)
845 {
846 static char *types[] = {
847 "reserved",
848 "asid-tagged VIVT",
849 "VIPT",
850 "PIPT",
851 };
852
853 if (type >= nelem(types) || types[type] == nil)
854 return "GOK";
855 return types[type];
856 }
857
858 void
cacheinfo(int level,Memcache * cp)859 cacheinfo(int level, Memcache *cp)
860 {
861 ulong setsways;
862
863 /* select cache level */
864 cpwrsc(CpIDcssel, CpID, CpIDid, 0, (level - 1) << 1);
865
866 setsways = cprdsc(CpIDcsize, CpID, CpIDid, 0);
867 cp->l1ip = cprdsc(0, CpID, CpIDidct, CpIDct);
868 cp->level = level;
869 cp->nways = ((setsways >> 3) & MASK(10)) + 1;
870 cp->nsets = ((setsways >> 13) & MASK(15)) + 1;
871 cp->log2linelen = (setsways & MASK(2)) + 2 + 2;
872 cp->linelen = 1 << cp->log2linelen;
873 cp->setsways = setsways;
874
875 cp->setsh = cp->log2linelen;
876 cp->waysh = 32 - log2(cp->nways);
877 }
878
879 static void
prcachecfg(void)880 prcachecfg(void)
881 {
882 int cache;
883 Memcache mc;
884
885 for (cache = 1; cache <= 2; cache++) {
886 cacheinfo(cache, &mc);
887 iprint("l%d: %d ways %d sets %d bytes/line",
888 mc.level, mc.nways, mc.nsets, mc.linelen);
889 if (mc.linelen != CACHELINESZ)
890 iprint(" *should* be %d", CACHELINESZ);
891 if (mc.setsways & Cawt)
892 iprint("; can WT");
893 if (mc.setsways & Cawb)
894 iprint("; can WB");
895 #ifdef COMPULSIVE /* both caches can do this */
896 if (mc.setsways & Cara)
897 iprint("; can read-allocate");
898 #endif
899 if (mc.setsways & Cawa)
900 iprint("; can write-allocate");
901 if (cache == 1)
902 iprint("; l1 I policy %s",
903 l1iptype((mc.l1ip >> 14) & MASK(2)));
904 iprint("\n");
905 }
906 }
907
908 static char *
subarch(int impl,uint sa)909 subarch(int impl, uint sa)
910 {
911 static char *armarchs[] = {
912 "VFPv1 (pre-armv7)",
913 "VFPv2 (pre-armv7)",
914 "VFPv3+ with common VFP subarch v2",
915 "VFPv3+ with null subarch",
916 "VFPv3+ with common VFP subarch v3",
917 };
918
919 if (impl != 'A' || sa >= nelem(armarchs))
920 return "GOK";
921 else
922 return armarchs[sa];
923 }
924
925 /*
926 * padconf bits in a short, 2 per long register
927 * 15 wakeupevent
928 * 14 wakeupenable
929 * 13 offpulltypeselect
930 * 12 offpulludenable
931 * 11 offoutvalue
932 * 10 offoutenable
933 * 9 offenable
934 * 8 inputenable
935 * 4 pulltypeselect
936 * 3 pulludenable
937 * 2-0 muxmode
938 *
939 * see table 7-5 in §7.4.4.3 of spruf98d
940 */
941
942 enum {
943 /* pad config register bits */
944 Inena = 1 << 8, /* input enable */
945 Indis = 0 << 8, /* input disable */
946 Ptup = 1 << 4, /* pull type up */
947 Ptdown = 0 << 4, /* pull type down */
948 Ptena = 1 << 3, /* pull type selection is active */
949 Ptdis = 0 << 3, /* pull type selection is inactive */
950 Muxmode = MASK(3),
951
952 /* pad config registers relevant to flash */
953 GpmcA1 = 0x4800207A,
954 GpmcA2 = 0x4800207C,
955 GpmcA3 = 0x4800207E,
956 GpmcA4 = 0x48002080,
957 GpmcA5 = 0x48002082,
958 GpmcA6 = 0x48002084,
959 GpmcA7 = 0x48002086,
960 GpmcA8 = 0x48002088,
961 GpmcA9 = 0x4800208A,
962 GpmcA10 = 0x4800208C,
963 GpmcD0 = 0x4800208E,
964 GpmcD1 = 0x48002090,
965 GpmcD2 = 0x48002092,
966 GpmcD3 = 0x48002094,
967 GpmcD4 = 0x48002096,
968 GpmcD5 = 0x48002098,
969 GpmcD6 = 0x4800209A,
970 GpmcD7 = 0x4800209C,
971 GpmcD8 = 0x4800209E,
972 GpmcD9 = 0x480020A0,
973 GpmcD10 = 0x480020A2,
974 GpmcD11 = 0x480020A4,
975 GpmcD12 = 0x480020A6,
976 GpmcD13 = 0x480020A8,
977 GpmcD14 = 0x480020AA,
978 GpmcD15 = 0x480020AC,
979 GpmcNCS0 = 0x480020AE,
980 GpmcNCS1 = 0x480020B0,
981 GpmcNCS2 = 0x480020B2,
982 GpmcNCS3 = 0x480020B4,
983 GpmcNCS4 = 0x480020B6,
984 GpmcNCS5 = 0x480020B8,
985 GpmcNCS6 = 0x480020BA,
986 GpmcNCS7 = 0x480020BC,
987 GpmcCLK = 0x480020BE,
988 GpmcNADV_ALE = 0x480020C0,
989 GpmcNOE = 0x480020C2,
990 GpmcNWE = 0x480020C4,
991 GpmcNBE0_CLE = 0x480020C6,
992 GpmcNBE1 = 0x480020C8,
993 GpmcNWP = 0x480020CA,
994 GpmcWAIT0 = 0x480020CC,
995 GpmcWAIT1 = 0x480020CE,
996 GpmcWAIT2 = 0x480020D0,
997 GpmcWAIT3 = 0x480020D2,
998 };
999
1000 /* set SCM pad config mux mode */
1001 void
setmuxmode(ulong addr,int shorts,int mode)1002 setmuxmode(ulong addr, int shorts, int mode)
1003 {
1004 int omode;
1005 ushort *ptr;
1006
1007 mode &= Muxmode;
1008 for (ptr = (ushort *)addr; shorts-- > 0; ptr++) {
1009 omode = *ptr & Muxmode;
1010 if (omode != mode)
1011 *ptr = *ptr & ~Muxmode | mode;
1012 }
1013 coherence();
1014 }
1015
1016 static void
setpadmodes(void)1017 setpadmodes(void)
1018 {
1019 int off;
1020
1021 /* set scm pad modes for usb; hasn't made any difference yet */
1022 setmuxmode(0x48002166, 7, 5); /* hsusb3_tll* in mode 5; is mode 4 */
1023 setmuxmode(0x48002180, 1, 5); /* hsusb3_tll_clk; is mode 4 */
1024 setmuxmode(0x48002184, 4, 5); /* hsusb3_tll_data?; is mode 1 */
1025 setmuxmode(0x480021a2, 12, 0); /* hsusb0 (console) in mode 0 */
1026 setmuxmode(0x480021d4, 6, 2); /* hsusb2_tll* (ehci port 2) in mode 2 */
1027 /* mode 3 is hsusb2_data* */
1028 setmuxmode(0x480025d8, 18, 6); /* hsusb[12]_tll*; mode 3 is */
1029 /* hsusb1_data*, hsusb2* */
1030
1031 setmuxmode(0x480020e4, 2, 5); /* uart3_rx_* in mode 5 */
1032 setmuxmode(0x4800219a, 4, 0); /* uart3_* in mode 0 */
1033 /* uart3_* in mode 2; TODO: conflicts with hsusb0 */
1034 setmuxmode(0x480021aa, 4, 2);
1035 setmuxmode(0x48002240, 2, 3); /* uart3_* in mode 3 */
1036
1037 /*
1038 * igep/gumstix only: mode 4 of 21d2 is gpio_176 (smsc9221 ether irq).
1039 * see ether9221.c for more.
1040 */
1041 *(ushort *)0x480021d2 = Inena | Ptup | Ptena | 4;
1042
1043 /* magic from u-boot for flash */
1044 *(ushort *)GpmcA1 = Indis | Ptup | Ptena | 0;
1045 *(ushort *)GpmcA2 = Indis | Ptup | Ptena | 0;
1046 *(ushort *)GpmcA3 = Indis | Ptup | Ptena | 0;
1047 *(ushort *)GpmcA4 = Indis | Ptup | Ptena | 0;
1048 *(ushort *)GpmcA5 = Indis | Ptup | Ptena | 0;
1049 *(ushort *)GpmcA6 = Indis | Ptup | Ptena | 0;
1050 *(ushort *)GpmcA7 = Indis | Ptup | Ptena | 0;
1051 *(ushort *)GpmcA8 = Indis | Ptup | Ptena | 0;
1052 *(ushort *)GpmcA9 = Indis | Ptup | Ptena | 0;
1053 *(ushort *)GpmcA10 = Indis | Ptup | Ptena | 0;
1054
1055 *(ushort *)GpmcD0 = Inena | Ptup | Ptena | 0;
1056 *(ushort *)GpmcD1 = Inena | Ptup | Ptena | 0;
1057 *(ushort *)GpmcD2 = Inena | Ptup | Ptena | 0;
1058 *(ushort *)GpmcD3 = Inena | Ptup | Ptena | 0;
1059 *(ushort *)GpmcD4 = Inena | Ptup | Ptena | 0;
1060 *(ushort *)GpmcD5 = Inena | Ptup | Ptena | 0;
1061 *(ushort *)GpmcD6 = Inena | Ptup | Ptena | 0;
1062 *(ushort *)GpmcD7 = Inena | Ptup | Ptena | 0;
1063 *(ushort *)GpmcD8 = Inena | Ptup | Ptena | 0;
1064 *(ushort *)GpmcD9 = Inena | Ptup | Ptena | 0;
1065 *(ushort *)GpmcD10 = Inena | Ptup | Ptena | 0;
1066 *(ushort *)GpmcD11 = Inena | Ptup | Ptena | 0;
1067 *(ushort *)GpmcD12 = Inena | Ptup | Ptena | 0;
1068 *(ushort *)GpmcD13 = Inena | Ptup | Ptena | 0;
1069 *(ushort *)GpmcD14 = Inena | Ptup | Ptena | 0;
1070 *(ushort *)GpmcD15 = Inena | Ptup | Ptena | 0;
1071
1072 *(ushort *)GpmcNCS0 = Indis | Ptup | Ptena | 0;
1073 *(ushort *)GpmcNCS1 = Indis | Ptup | Ptena | 0;
1074 *(ushort *)GpmcNCS2 = Indis | Ptup | Ptena | 0;
1075 *(ushort *)GpmcNCS3 = Indis | Ptup | Ptena | 0;
1076 *(ushort *)GpmcNCS4 = Indis | Ptup | Ptena | 0;
1077 *(ushort *)GpmcNCS5 = Indis | Ptup | Ptena | 0;
1078 *(ushort *)GpmcNCS6 = Indis | Ptup | Ptena | 0;
1079
1080 *(ushort *)GpmcNOE = Indis | Ptdown | Ptdis | 0;
1081 *(ushort *)GpmcNWE = Indis | Ptdown | Ptdis | 0;
1082
1083 *(ushort *)GpmcWAIT2 = Inena | Ptup | Ptena | 4; /* GPIO_64 -ETH_NRESET */
1084 *(ushort *)GpmcNCS7 = Inena | Ptup | Ptena | 1; /* SYS_nDMA_REQ3 */
1085
1086 *(ushort *)GpmcCLK = Indis | Ptdown | Ptdis | 0;
1087
1088 *(ushort *)GpmcNBE1 = Inena | Ptdown | Ptdis | 0;
1089
1090 *(ushort *)GpmcNADV_ALE = Indis | Ptdown | Ptdis | 0;
1091 *(ushort *)GpmcNBE0_CLE = Indis | Ptdown | Ptdis | 0;
1092
1093 *(ushort *)GpmcNWP = Inena | Ptdown | Ptdis | 0;
1094
1095 *(ushort *)GpmcWAIT0 = Inena | Ptup | Ptena | 0;
1096 *(ushort *)GpmcWAIT1 = Inena | Ptup | Ptena | 0;
1097 *(ushort *)GpmcWAIT3 = Inena | Ptup | Ptena | 0;
1098
1099 /*
1100 * magic from u-boot: set 0xe00 bits in gpmc_(nwe|noe|nadv_ale)
1101 * to enable `off' mode for each.
1102 */
1103 for (off = 0xc0; off <= 0xc4; off += sizeof(short))
1104 *((ushort *)(PHYSSCM + off)) |= 0xe00;
1105 coherence();
1106 }
1107
1108 static char *
implement(uchar impl)1109 implement(uchar impl)
1110 {
1111 if (impl == 'A')
1112 return "arm";
1113 else
1114 return "unknown";
1115 }
1116
1117 static void
fpon(void)1118 fpon(void)
1119 {
1120 int gotfp, impl;
1121 ulong acc, scr;
1122
1123 gotfp = 1 << CpFP | 1 << CpDFP;
1124 cpwrsc(0, CpCONTROL, 0, CpCPaccess, MASK(28));
1125 acc = cprdsc(0, CpCONTROL, 0, CpCPaccess);
1126 if ((acc & (MASK(2) << (2*CpFP))) == 0) {
1127 gotfp &= ~(1 << CpFP);
1128 print("fpon: no single FP coprocessor\n");
1129 }
1130 if ((acc & (MASK(2) << (2*CpDFP))) == 0) {
1131 gotfp &= ~(1 << CpDFP);
1132 print("fpon: no double FP coprocessor\n");
1133 }
1134 if (!gotfp) {
1135 print("fpon: no FP coprocessors\n");
1136 return;
1137 }
1138
1139 /* enable fp. must be first operation on the FPUs. */
1140 fpwr(Fpexc, fprd(Fpexc) | 1 << 30);
1141
1142 scr = fprd(Fpsid);
1143 impl = scr >> 24;
1144 print("fp: %s arch %s", implement(impl),
1145 subarch(impl, (scr >> 16) & MASK(7)));
1146
1147 scr = fprd(Fpscr);
1148 // TODO configure Fpscr further
1149 scr |= 1 << 9; /* div-by-0 exception */
1150 scr &= ~(MASK(2) << 20 | MASK(3) << 16); /* all ops are scalar */
1151 fpwr(Fpscr, scr);
1152 print("\n");
1153 /* we should now be able to execute VFP-style FP instr'ns natively */
1154 }
1155
1156 static void
resetusb(void)1157 resetusb(void)
1158 {
1159 int bound;
1160 Uhh *uhh;
1161 Usbotg *otg;
1162 Usbtll *tll;
1163
1164 iprint("resetting usb: otg...");
1165 otg = (Usbotg *)PHYSUSBOTG;
1166 otg->otgsyscfg = Softreset; /* see omap35x errata 3.1.1.144 */
1167 coherence();
1168 resetwait(&otg->otgsyssts);
1169 otg->otgsyscfg |= Sidle | Midle;
1170 coherence();
1171
1172 iprint("uhh...");
1173 uhh = (Uhh *)PHYSUHH;
1174 uhh->sysconfig |= Softreset;
1175 coherence();
1176 resetwait(&uhh->sysstatus);
1177 for (bound = 400*Mhz; !(uhh->sysstatus & Resetdone) && bound > 0;
1178 bound--)
1179 ;
1180 uhh->sysconfig |= Sidle | Midle;
1181
1182 /*
1183 * using the TLL seems to be an optimisation when talking
1184 * to another identical SoC, thus not very useful, so
1185 * force PHY (ULPI) mode.
1186 */
1187 /* this bit is normally off when we get here */
1188 uhh->hostconfig &= ~P1ulpi_bypass;
1189 coherence();
1190 if (uhh->hostconfig & P1ulpi_bypass)
1191 iprint("utmi (tll) mode..."); /* via tll */
1192 else
1193 /* external transceiver (phy), no tll */
1194 iprint("ulpi (phy) mode...");
1195
1196 tll = (Usbtll *)PHYSUSBTLL;
1197 if (probeaddr(PHYSUSBTLL) >= 0) {
1198 iprint("tll...");
1199 tll->sysconfig |= Softreset;
1200 coherence();
1201 resetwait(&tll->sysstatus);
1202 tll->sysconfig |= Sidle;
1203 coherence();
1204 } else
1205 iprint("no tll...");
1206 iprint("\n");
1207 }
1208
1209 /*
1210 * there are secure sdrc registers at 0x48002460
1211 * sdrc regs at PHYSSDRC; see spruf98c §1.2.8.2.
1212 * set or dump l4 prot regs at PHYSL4?
1213 */
1214 void
archreset(void)1215 archreset(void)
1216 {
1217 static int beenhere;
1218
1219 if (beenhere)
1220 return;
1221 beenhere = 1;
1222
1223 /* conservative temporary values until archconfinit runs */
1224 m->cpuhz = 500 * Mhz; /* beagle speed */
1225 m->delayloop = m->cpuhz/2000; /* initial estimate */
1226
1227 // dumpl3pr();
1228 prcachecfg();
1229 /* fight omap35x errata 2.0.1.104 */
1230 memset((void *)PHYSSWBOOTCFG, 0, 240);
1231 coherence();
1232
1233 setpadmodes();
1234 configclks(); /* may change cpu speed */
1235 configgpio();
1236
1237 archconfinit();
1238
1239 resetusb();
1240 fpon();
1241 }
1242
1243 void
archreboot(void)1244 archreboot(void)
1245 {
1246 Prm *prm = (Prm *)PHYSPRMGLBL;
1247
1248 iprint("archreboot: reset!\n");
1249 delay(20);
1250
1251 prm->rstctrl |= Rstgs;
1252 coherence();
1253 delay(500);
1254
1255 /* shouldn't get here */
1256 splhi();
1257 iprint("awaiting reset");
1258 for(;;) {
1259 delay(1000);
1260 print(".");
1261 }
1262 }
1263
1264 void
kbdinit(void)1265 kbdinit(void)
1266 {
1267 }
1268
1269 void
lastresortprint(char * buf,long bp)1270 lastresortprint(char *buf, long bp)
1271 {
1272 iprint("%.*s", (int)bp, buf); /* nothing else seems to work */
1273 }
1274
1275 static void
scmdump(ulong addr,int shorts)1276 scmdump(ulong addr, int shorts)
1277 {
1278 ushort reg;
1279 ushort *ptr;
1280
1281 ptr = (ushort *)addr;
1282 print("scm regs:\n");
1283 while (shorts-- > 0) {
1284 reg = *ptr++;
1285 print("%#p: %#ux\tinputenable %d pulltypeselect %d "
1286 "pulludenable %d muxmode %d\n",
1287 ptr, reg, (reg>>8) & 1, (reg>>4) & 1, (reg>>3) & 1,
1288 reg & 7);
1289 }
1290 }
1291
1292 char *cputype2name(char *buf, int size);
1293
1294 void
cpuidprint(void)1295 cpuidprint(void)
1296 {
1297 char name[64];
1298
1299 cputype2name(name, sizeof name);
1300 delay(250); /* let uart catch up */
1301 iprint("cpu%d: %lldMHz ARM %s\n", m->machno, m->cpuhz / Mhz, name);
1302 }
1303
1304 static void
missing(ulong addr,char * name)1305 missing(ulong addr, char *name)
1306 {
1307 static int firstmiss = 1;
1308
1309 if (probeaddr(addr) >= 0)
1310 return;
1311 if (firstmiss) {
1312 iprint("missing:");
1313 firstmiss = 0;
1314 } else
1315 iprint(",\n\t");
1316 iprint(" %s at %#lux", name, addr);
1317 }
1318
1319 /* verify that all the necessary device registers are accessible */
1320 void
chkmissing(void)1321 chkmissing(void)
1322 {
1323 delay(20);
1324 missing(PHYSSCM, "scm");
1325 missing(KZERO, "dram");
1326 missing(PHYSL3, "l3 config");
1327 missing(PHYSINTC, "intr ctlr");
1328 missing(PHYSTIMER1, "timer1");
1329 missing(PHYSCONS, "console uart2");
1330 missing(PHYSUART0, "uart0");
1331 missing(PHYSUART1, "uart1");
1332 missing(PHYSETHER, "smc9221"); /* not on beagle */
1333 missing(PHYSUSBOTG, "usb otg");
1334 missing(PHYSUHH, "usb uhh");
1335 missing(PHYSOHCI, "usb ohci");
1336 missing(PHYSEHCI, "usb ehci");
1337 missing(PHYSSDMA, "dma");
1338 missing(PHYSWDOG, "watchdog timer");
1339 missing(PHYSUSBTLL, "usb tll");
1340 iprint("\n");
1341 delay(20);
1342 }
1343
1344 void
archflashwp(Flash *,int)1345 archflashwp(Flash*, int)
1346 {
1347 }
1348
1349 /*
1350 * for ../port/devflash.c:/^flashreset
1351 * retrieve flash type, virtual base and length and return 0;
1352 * return -1 on error (no flash)
1353 */
1354 int
archflashreset(int bank,Flash * f)1355 archflashreset(int bank, Flash *f)
1356 {
1357 if(bank != 0)
1358 return -1;
1359 /*
1360 * this is set up for the igepv2 board.
1361 * if the beagleboard ever works, we'll have to sort this out.
1362 */
1363 f->type = "onenand";
1364 f->addr = (void*)PHYSNAND; /* mapped here by archreset */
1365 f->size = 0; /* done by probe */
1366 f->width = 1;
1367 f->interleave = 0;
1368 return 0;
1369 }
1370