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