xref: /plan9-contrib/sys/src/9/bcm/archbcm.c (revision 5c47fe09a0cc86dfb02c0ea4a2b6aec7eda2361f)
15d9de2d3SDavid du Colombier /*
2*5c47fe09SDavid du Colombier  * bcm2835 (e.g. original raspberry pi) architecture-specific stuff
35d9de2d3SDavid du Colombier  */
45d9de2d3SDavid du Colombier 
55d9de2d3SDavid du Colombier #include "u.h"
65d9de2d3SDavid du Colombier #include "../port/lib.h"
75d9de2d3SDavid du Colombier #include "mem.h"
85d9de2d3SDavid du Colombier #include "dat.h"
95d9de2d3SDavid du Colombier #include "fns.h"
105d9de2d3SDavid du Colombier #include "../port/error.h"
115d9de2d3SDavid du Colombier #include "io.h"
125d9de2d3SDavid du Colombier #include "arm.h"
135d9de2d3SDavid du Colombier 
145d9de2d3SDavid du Colombier #include "../port/netif.h"
155d9de2d3SDavid du Colombier #include "etherif.h"
165d9de2d3SDavid du Colombier 
175d9de2d3SDavid du Colombier #define	POWERREGS	(VIRTIO+0x100000)
185d9de2d3SDavid du Colombier 
19*5c47fe09SDavid du Colombier Soc soc = {
20*5c47fe09SDavid du Colombier 	.dramsize	= 512*MiB,
21*5c47fe09SDavid du Colombier 	.physio		= 0x20000000,
22*5c47fe09SDavid du Colombier 	.busdram	= 0x40000000,
23*5c47fe09SDavid du Colombier 	.busio		= 0x7E000000,
24*5c47fe09SDavid du Colombier 	.armlocal	= 0,
25*5c47fe09SDavid du Colombier 	.l1ptedramattrs = Cached | Buffered,
26*5c47fe09SDavid du Colombier 	.l2ptedramattrs = Cached | Buffered,
27*5c47fe09SDavid du Colombier };
28*5c47fe09SDavid du Colombier 
295d9de2d3SDavid du Colombier enum {
305d9de2d3SDavid du Colombier 	Wdogfreq	= 65536,
31*5c47fe09SDavid du Colombier 	Wdogtime	= 10,	/* seconds, ≤ 15 */
325d9de2d3SDavid du Colombier };
335d9de2d3SDavid du Colombier 
345d9de2d3SDavid du Colombier /*
355d9de2d3SDavid du Colombier  * Power management / watchdog registers
365d9de2d3SDavid du Colombier  */
375d9de2d3SDavid du Colombier enum {
385d9de2d3SDavid du Colombier 	Rstc		= 0x1c>>2,
395d9de2d3SDavid du Colombier 		Password	= 0x5A<<24,
405d9de2d3SDavid du Colombier 		CfgMask		= 0x03<<4,
415d9de2d3SDavid du Colombier 		CfgReset	= 0x02<<4,
42da091934SDavid du Colombier 	Rsts		= 0x20>>2,
435d9de2d3SDavid du Colombier 	Wdog		= 0x24>>2,
445d9de2d3SDavid du Colombier };
455d9de2d3SDavid du Colombier 
465d9de2d3SDavid du Colombier void
archreset(void)475d9de2d3SDavid du Colombier archreset(void)
485d9de2d3SDavid du Colombier {
495d9de2d3SDavid du Colombier 	fpon();
505d9de2d3SDavid du Colombier }
515d9de2d3SDavid du Colombier 
525d9de2d3SDavid du Colombier void
archreboot(void)535d9de2d3SDavid du Colombier archreboot(void)
545d9de2d3SDavid du Colombier {
555d9de2d3SDavid du Colombier 	u32int *r;
565d9de2d3SDavid du Colombier 
575d9de2d3SDavid du Colombier 	r = (u32int*)POWERREGS;
585d9de2d3SDavid du Colombier 	r[Wdog] = Password | 1;
595d9de2d3SDavid du Colombier 	r[Rstc] = Password | (r[Rstc] & ~CfgMask) | CfgReset;
605d9de2d3SDavid du Colombier 	coherence();
615d9de2d3SDavid du Colombier 	for(;;)
625d9de2d3SDavid du Colombier 		;
635d9de2d3SDavid du Colombier }
645d9de2d3SDavid du Colombier 
65*5c47fe09SDavid du Colombier void
wdogfeed(void)66da091934SDavid du Colombier wdogfeed(void)
67da091934SDavid du Colombier {
68da091934SDavid du Colombier 	u32int *r;
69da091934SDavid du Colombier 
70da091934SDavid du Colombier 	r = (u32int*)POWERREGS;
71da091934SDavid du Colombier 	r[Wdog] = Password | (Wdogtime * Wdogfreq);
72da091934SDavid du Colombier 	r[Rstc] = Password | (r[Rstc] & ~CfgMask) | CfgReset;
73da091934SDavid du Colombier }
74da091934SDavid du Colombier 
75da091934SDavid du Colombier void
wdogoff(void)76da091934SDavid du Colombier wdogoff(void)
77da091934SDavid du Colombier {
78da091934SDavid du Colombier 	u32int *r;
79da091934SDavid du Colombier 
80da091934SDavid du Colombier 	r = (u32int*)POWERREGS;
81da091934SDavid du Colombier 	r[Rstc] = Password | (r[Rstc] & ~CfgMask);
82da091934SDavid du Colombier }
83da091934SDavid du Colombier 
84*5c47fe09SDavid du Colombier char *
cputype2name(char * buf,int size)85*5c47fe09SDavid du Colombier cputype2name(char *buf, int size)
86*5c47fe09SDavid du Colombier {
87*5c47fe09SDavid du Colombier 	seprint(buf, buf + size, "1176JZF-S");
88*5c47fe09SDavid du Colombier 	return buf;
89*5c47fe09SDavid du Colombier }
90*5c47fe09SDavid du Colombier 
915d9de2d3SDavid du Colombier void
cpuidprint(void)925d9de2d3SDavid du Colombier cpuidprint(void)
935d9de2d3SDavid du Colombier {
94*5c47fe09SDavid du Colombier 	char name[64];
95*5c47fe09SDavid du Colombier 
96*5c47fe09SDavid du Colombier 	cputype2name(name, sizeof name);
97*5c47fe09SDavid du Colombier 	delay(50);				/* let uart catch up */
98*5c47fe09SDavid du Colombier 	print("cpu%d: %dMHz ARM %s\n", m->machno, m->cpumhz, name);
99*5c47fe09SDavid du Colombier }
100*5c47fe09SDavid du Colombier 
101*5c47fe09SDavid du Colombier int
getncpus(void)102*5c47fe09SDavid du Colombier getncpus(void)
103*5c47fe09SDavid du Colombier {
104*5c47fe09SDavid du Colombier 	return 1;
105*5c47fe09SDavid du Colombier }
106*5c47fe09SDavid du Colombier 
107*5c47fe09SDavid du Colombier int
startcpus(uint)108*5c47fe09SDavid du Colombier startcpus(uint)
109*5c47fe09SDavid du Colombier {
110*5c47fe09SDavid du Colombier 	return 1;
1115d9de2d3SDavid du Colombier }
1125d9de2d3SDavid du Colombier 
1135d9de2d3SDavid du Colombier void
archbcmlink(void)1145d9de2d3SDavid du Colombier archbcmlink(void)
1155d9de2d3SDavid du Colombier {
116da091934SDavid du Colombier 	addclock0link(wdogfeed, HZ);
1175d9de2d3SDavid du Colombier }
1185d9de2d3SDavid du Colombier 
1195d9de2d3SDavid du Colombier int
archether(unsigned ctlrno,Ether * ether)1205d9de2d3SDavid du Colombier archether(unsigned ctlrno, Ether *ether)
1215d9de2d3SDavid du Colombier {
1225d9de2d3SDavid du Colombier 	ether->type = "usb";
1235d9de2d3SDavid du Colombier 	ether->ctlrno = ctlrno;
1245d9de2d3SDavid du Colombier 	ether->irq = -1;
1255d9de2d3SDavid du Colombier 	ether->nopt = 0;
1265d9de2d3SDavid du Colombier 	return 1;
1275d9de2d3SDavid du Colombier }
128*5c47fe09SDavid du Colombier 
129*5c47fe09SDavid du Colombier int
l2ap(int ap)130*5c47fe09SDavid du Colombier l2ap(int ap)
131*5c47fe09SDavid du Colombier {
132*5c47fe09SDavid du Colombier 	return (AP(3, (ap))|AP(2, (ap))|AP(1, (ap))|AP(0, (ap)));
133*5c47fe09SDavid du Colombier }
134*5c47fe09SDavid du Colombier 
135*5c47fe09SDavid du Colombier /*
136*5c47fe09SDavid du Colombier  * atomic ops
137*5c47fe09SDavid du Colombier  * make sure that we don't drag in the C library versions
138*5c47fe09SDavid du Colombier  */
139*5c47fe09SDavid du Colombier 
140*5c47fe09SDavid du Colombier long
ainc(long * p)141*5c47fe09SDavid du Colombier ainc(long *p)
142*5c47fe09SDavid du Colombier {
143*5c47fe09SDavid du Colombier 	int s, v;
144*5c47fe09SDavid du Colombier 
145*5c47fe09SDavid du Colombier 	s = splhi();
146*5c47fe09SDavid du Colombier 	v = ++*p;
147*5c47fe09SDavid du Colombier 	splx(s);
148*5c47fe09SDavid du Colombier 	return v;
149*5c47fe09SDavid du Colombier }
150*5c47fe09SDavid du Colombier 
151*5c47fe09SDavid du Colombier long
adec(long * p)152*5c47fe09SDavid du Colombier adec(long *p)
153*5c47fe09SDavid du Colombier {
154*5c47fe09SDavid du Colombier 	int s, v;
155*5c47fe09SDavid du Colombier 
156*5c47fe09SDavid du Colombier 	s = splhi();
157*5c47fe09SDavid du Colombier 	v = --*p;
158*5c47fe09SDavid du Colombier 	splx(s);
159*5c47fe09SDavid du Colombier 	return v;
160*5c47fe09SDavid du Colombier }
161*5c47fe09SDavid du Colombier 
162*5c47fe09SDavid du Colombier int
cas32(void * addr,u32int old,u32int new)163*5c47fe09SDavid du Colombier cas32(void* addr, u32int old, u32int new)
164*5c47fe09SDavid du Colombier {
165*5c47fe09SDavid du Colombier 	int r, s;
166*5c47fe09SDavid du Colombier 
167*5c47fe09SDavid du Colombier 	s = splhi();
168*5c47fe09SDavid du Colombier 	if(r = (*(u32int*)addr == old))
169*5c47fe09SDavid du Colombier 		*(u32int*)addr = new;
170*5c47fe09SDavid du Colombier 	splx(s);
171*5c47fe09SDavid du Colombier 	if (r)
172*5c47fe09SDavid du Colombier 		coherence();
173*5c47fe09SDavid du Colombier 	return r;
174*5c47fe09SDavid du Colombier }
175*5c47fe09SDavid du Colombier 
176*5c47fe09SDavid du Colombier int
cmpswap(long * addr,long old,long new)177*5c47fe09SDavid du Colombier cmpswap(long *addr, long old, long new)
178*5c47fe09SDavid du Colombier {
179*5c47fe09SDavid du Colombier 	return cas32(addr, old, new);
1805d9de2d3SDavid du Colombier }
1815d9de2d3SDavid du Colombier 
182