xref: /inferno-os/os/boot/mpc/initfads.c (revision 6e425a9de8c003b5a733621a6b6730ec3cc902b8)
1 /*
2  * Called from l.s in EPROM to set up a minimal working environment.
3  * Since there is no DRAM yet, and therefore no stack, no function
4  * calls may be made from sysinit0, and values can't be stored,
5  * except to INTMEM.  Global values are accessed by offset from SB,
6  * which has been set by l.s to point into EPROM.
7  *
8  * This is FADS-specific in CS assignment and access of the FADS BCSR
9  * to discover memory size and speed.
10  */
11 
12 #include "u.h"
13 #include "lib.h"
14 #include "mem.h"
15 #include "dat.h"
16 #include "fns.h"
17 #include "io.h"
18 
19 #include "archfads.h"
20 
21 #define	MB	(1024*1024)
22 
23 enum {
24 	UPMSIZE = 64,	/* memory controller instruction RAM */
25 	SPEED = 50,	/* maximum memory clock in MHz */
26 	SDRAMSIZE = 4*MB,
27 
28 	/* mcr */
29 	WriteRAM = 0<<30,
30 	ReadRAM = 1<<30,
31 	ExecRAM = 2<<30,
32 
33 	SelUPMA = 0<<23,
34 	SelUPMB = 1<<23,
35 
36 	Once = 1<<8,
37 };
38 
39 /*
40  * mpc8bug uses the following for 60ns EDO DRAMs 32-50MHz
41  */
42 static ulong upma50[UPMSIZE] = {
43 	0x8FFFEC24,	0xFFFEC04,	0xCFFEC04,	0xFFEC04,
44 	0xFFEC00,	0x37FFEC47,	0xFFFFFFFF,	0xFFFFFFFF,
45 	0x8FFFEC24,	0xFFFEC04,	0x8FFEC04,	0xFFEC0C,
46 	0x3FFEC00,	0xFFEC44,	0xFFCC08,	0xCFFCC44,
47 	0xFFEC0C,	0x3FFEC00,	0xFFEC44,	0xFFCC00,
48 	0x3FFFC847,	0x3FFFEC47,	0xFFFFFFFF,	0xFFFFFFFF,
49 	0x8FAFCC24,	0xFAFCC04,	0xCAFCC00,	0x11BFCC47,
50 	0xC0FFCC84,	0xFFFFFFFF,	0xFFFFFFFF,	0xFFFFFFFF,
51 	0x8FAFCC24,	0xFAFCC04,	0xCAFCC00,	0x3AFCC4C,
52 	0xCAFCC00,	0x3AFCC4C,	0xCAFCC00,	0x3AFCC4C,
53 	0xCAFCC00,	0x33BFCC4F,	0xFFFFFFFF,	0xFFFFFFFF,
54 	0xFFFFFFFF,	0xFFFFFFFF,	0xFFFFFFFF,	0xFFFFFFFF,
55 	0xC0FFCC84,	0xFFCC04,	0x7FFCC04,	0x3FFFCC06,
56 	0xFFFFCC85,	0xFFFFCC05,	0xFFFFCC05,	0xFFFFFFFF,
57 	0xFFFFFFFF,	0xFFFFFFFF,	0xFFFFFFFF,	0xFFFFFFFF,
58 	0x33FFCC07,	0xFFFFFFFF,	0xFFFFFFFF,	0xFFFFFFFF,
59 };
60 
61 /*
62  * the FADS manual table 3-7 suggests the following for 60ns EDO DRAMs at 20MHz
63  */
64 static ulong upma20[UPMSIZE] = {
65 	0x8FFFCC04, 0x08FFCC00, 0x33FFCC47, ~0, ~0, ~0, ~0, ~0,
66 	[0x08]	0x8FFFCC04, 0x08FFCC08, 0x08FFCC08, 0x08FFCC08, 0x08FFCC00, 0x3FFFCC47, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
67 	[0x18]	0x8FEFCC00, 0x39BFCC47, ~0, ~0, ~0, ~0, ~0, ~0,
68 	[0x20]	0x8FEFCC00, 0x09AFCC48, 0x09AFCC48, 0x08AFCC48, 0x39BFCC47, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
69 	[0x30]	0x80FFCC84, 0x17FFCC04, 0xFFFFCC86, 0xFFFFCC05, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
70 	[0x3C]	0x33FFCC07, ~0, ~0, ~0,
71 };
72 
73 void
74 sysinit0(int inrom)
75 {
76 	ulong *upm, *bcsr;
77 	IMM *io;
78 	int i, mb;
79 
80 	io = (IMM*)INTMEM;		/* running before maps, no KADDR */
81 
82 	/* system interface unit initialisation, FADS manual table 3-2, except as noted */
83 	io->siumcr = 0x01012440;
84 	io->sypcr = 0xFFFFFF88;
85 	io->tbscrk = KEEP_ALIVE_KEY;
86 	io->tbscr = 0xC3;	/* time base enabled */
87 	io->rtcsck = KEEP_ALIVE_KEY;
88 	io->rtcsc = 0xC1;	/* don't FRZ, real-time clock enabled */
89 	io->rtcsck = ~KEEP_ALIVE_KEY;
90 	io->piscrk = KEEP_ALIVE_KEY;
91 	io->piscr = 0x82;
92 
93 	io->memc[BCSRCS].option = 0xFFFF8110;	/* 32k block, all types access, CS early negate, 1 ws */
94 	io->memc[BCSRCS].base = BCSRMEM | 1;	/* base, 32-bit port, no parity, GPCM */
95 
96 	io->memc[BOOTCS].base = FLASHMEM | 1;
97 	io->memc[BOOTCS].option = 0xFF800D54;
98 
99 	if(!inrom)
100 		return;	/* can't initialise DRAM controller from DRAM */
101 
102 	bcsr = (ulong*)BCSRMEM;
103 //	bcsr[1] &= ~DisableDRAM;
104 	/* could check DRAM speed here; assume 60ns */
105 	switch((bcsr[2]>>23)&3){
106 	default:	return;	/* can't happen; for the compiler */
107 	case 0:	mb = 4; break;
108 	case 1:	mb = 32; break;
109 	case 2:	mb = 16; break;
110 	case 3:	mb = 8; break;
111 	}
112 
113 	upm = upma50;
114 	for(i=0; i<UPMSIZE; i++){
115 		io->mdr = upm[i];
116 		io->mcr = WriteRAM | SelUPMA | i;
117 	}
118 	io->mptpr = 0x0400;
119 	if(SPEED >= 32)
120 		io->mamr = (0x9C<<24) | 0xA21114;	/* 50MHz BRGCLK; FADS manual says 0xC0, mpc8bug sets 0x9C */
121 	else if(SPEED >= 20)
122 		io->mamr = (0x60<<24) | 0xA21114;	/* 25MHz BRGCLK */
123 	else
124 		io->mamr = (0x40<<24) | 0xA21114;	/* 16.67MHz BRGCLK */
125 	io->memc[DRAM1].option = ~((mb<<20)-1)|0x0800;	/* address mask, SAM=1 */
126 	io->memc[DRAM1].base = 0 | 0x81;	/* base at 0, 32-bit port size, no parity, UPMA */
127 }
128 
129 /*
130  * the FADS manual table 3-9's suggestion for MB811171622A-100 32+MHz-50MHz
131  */
132 static ulong upmb50[UPMSIZE] = {
133 	[0x00]	0x1F07FC04, 0xEEAEFC04, 0x11ADFC04, 0xEFBBBC00, 0x1FF77C47,
134 	[0x05]	0x1FF77C34, 0xEFEABC34, 0x1FB57C35,
135 	[0x08]	0x1F07FC04, 0xEEAEFC04, 0x10ADFC04, 0xF0AFFC00, 0xF0AFFC00, 0xF1AFFC00, 0xEFBBBC00, 0x1FF77C47, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
136 	[0x18]	0x1F27FC04, 0xEEAEBC00, 0x01B93C04, 0x1FF77C47, ~0, ~0, ~0, ~0,
137 	[0x20]	0x1F07FC04, 0xEEAEBC00, 0x10AD7C00, 0xF0AFFC00, 0xF0AFFC00, 0xE1BBBC04, 0x1FF77C47, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
138 	[0x30] 	0x1FF5FC84, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC84, 0xFFFFFC07, ~0, ~0, ~0, ~0, ~0, ~0,
139 	[0x3C]	0x7FFFFC07, ~0, ~0, ~0,
140 };
141 
142 /*
143  * the FADS manual table 3-8's suggestion for MB811171622A-100 up to 32MHz
144  */
145 static	ulong	upmb32[UPMSIZE] = {
146 	[0x00]	0x126CC04, 0xFB98C00, 0x1FF74C45, ~0, ~0,
147 	[0x05]	0x1FE77C34, 0xEFAABC34, 0x1FA57C35,
148 	[0x08]	0x0026FC04, 0x10ADFC00, 0xF0AFFC00, 0xF1AFFC00, 0xEFBBBC00, 0x1FF77C45, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
149 	[0x18]	0x0E26BC04, 0x01B93C00, 0x1FF77C45, ~0, ~0, ~0, ~0, ~0,
150 	[0x20]	0x0E26BC00, 0x10AD7C00, 0xF0AFFC00, 0xF0AFFC00, 0xE1BBBC04, 0x1FF77C45, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
151 	[0x30]	0x1FF5FC84, 0xFFFFFC04, 0xFFFFFC84, 0xFFFFFC05, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
152 	[0x3C]	0x7FFFFC07, ~0, ~0, ~0,
153 };
154 
155 /*
156  * optionally called by archfads.c:/^archinit to initialise access to SDRAM
157  */
158 void
159 sdraminit(ulong base)
160 {
161 	ulong *upm;
162 	IMM *io;
163 	int i;
164 
165 	io = (IMM*)INTMEM;		/* running before maps, no KADDR */
166 	if(SPEED > 32)
167 		upm = upmb50;
168 	else
169 		upm = upmb32;
170 	for(i=0; i<UPMSIZE; i++){
171 		io->mdr = upm[i];
172 		io->mcr = WriteRAM | SelUPMB | i;
173 	}
174 	io->memc[SDRAM].option = ~(SDRAMSIZE-1)|0x0A00;	/* address mask, SAM=1, G5LS=1 */
175 	io->memc[SDRAM].base = base | 0xC1;
176 	if(SPEED > 32){
177 		io->mbmr = 0xD0802114;	/* 50MHz BRGCLK */
178 		io->mar = 0x88;
179 	}else{
180 		io->mbmr = 0x80802114;	/* 32MHz BRGCLK */
181 		io->mar = 0x48;
182 	}
183 	io->mcr = ExecRAM | SelUPMB | (SDRAM<<13) | Once | 5;	/* run MRS command in locations 5-8 of UPMB */
184 	io->mbmr = (io->mbmr & ~0xF) | 8;
185 	io->mcr = ExecRAM | SelUPMB | (SDRAM<<13) | Once | 0x30;	/* run refresh sequence */
186 	io->mbmr = (io->mbmr & ~0xF) | 4;	/* 4-beat refresh bursts */
187 }
188