1 #include "u.h" 2 #include "lib.h" 3 #include "mem.h" 4 #include "dat.h" 5 #include "fns.h" 6 #include "io.h" 7 #include "archfads.h" 8 9 /* 10 * board-specific support for the 8xxFADS (including 860/21 development system) 11 */ 12 13 enum { 14 USESDRAM = 0, /* set to 1 if kernel is to use SDRAM as well as DRAM */ 15 16 /* sccr */ 17 RTSEL = IBIT(8), /* =0, select main oscillator (OSCM); =1, select external crystal (EXTCLK) */ 18 RTDIV = IBIT(7), /* =0, divide by 4; =1, divide by 512 */ 19 CRQEN = IBIT(9), /* =1, switch to high frequency when CPM active */ 20 PRQEN = IBIT(10), /* =1, switch to high frequency when interrupt pending */ 21 22 /* plprcr */ 23 CSRC = IBIT(21), /* =0, clock is DFNH; =1, clock is DFNL */ 24 }; 25 26 /* 27 * called early in main.c, after machinit: 28 * using board and architecture specific registers, initialise 29 * 8xx registers that need it and complete initialisation of the Mach structure. 30 */ 31 void 32 archinit(void) 33 { 34 IMM *io; 35 int mf, isfads, sysmhz, t; 36 ulong v; 37 38 v = getimmr() & 0xFFFF; 39 isfads = 0; /* assume it's the 860/821 board */ 40 sysmhz = 40; 41 switch(v>>8){ 42 case 0x00: t = 0x86000; break; 43 case 0x20: t = 0x82300; isfads = 1; break; 44 case 0x21: t = 0x823a0; isfads = 1; break; 45 default: t = 0; break; 46 } 47 m->cputype = t; 48 m->bcsr = KADDR(BCSRMEM); 49 m->bcsr[1] |= DisableRS232a | DisableIR | DisableEther | DisablePCMCIA | DisableRS232b; 50 m->bcsr[1] &= ~(DisableDRAM|DisableFlash); 51 if(isfads){ 52 sysmhz = 50; 53 m->bcsr[1] &= ~EnableSDRAM; 54 m->bcsr[4] &= ~(EnableVideoClock|EnableVideoPort); 55 m->bcsr[4] |= DisableVideoLamp; 56 } 57 io = m->iomem; 58 if(1 || io->sccr & IBIT(7)){ /* RTDIV=1 */ 59 /* oscillator frequency can't be determined independently: check a switch */ 60 if((m->bcsr[2]>>19)&(1<<2)) 61 m->clockgen = 5*MHz; 62 else 63 m->clockgen = 4*MHz; 64 } else 65 m->clockgen = 32768; 66 mf = (sysmhz*MHz)/m->clockgen; 67 m->cpuhz = m->clockgen*mf; 68 io->plprcrk = KEEP_ALIVE_KEY; 69 io->plprcr &= ~IBIT(21); /* general system clock is DFNH */ 70 io->plprcr = (io->plprcr & ((1<<20)-1)) | ((mf-1)<<20); 71 io->mptpr = 0x0400; /* memory prescaler = 16 for refresh */ 72 io->plprcrk = ~KEEP_ALIVE_KEY; 73 if(isfads){ 74 m->bcsr[1] |= EnableSDRAM; 75 sdraminit(SDRAMMEM); 76 if(!USESDRAM) 77 m->bcsr[1] &= ~EnableSDRAM; /* tells kernel not to map it */ 78 } 79 } 80 81 static void 82 archidprint(void) 83 { 84 int f, i; 85 ulong v; 86 87 /* 8xx and FADS specific */ 88 print("IMMR: "); 89 v = getimmr() & 0xFFFF; 90 switch(v>>8){ 91 case 0x00: print("MPC860/821"); break; 92 case 0x20: print("MPC823"); break; 93 case 0x21: print("MPC823A"); break; 94 default: print("Type #%lux", v>>8); break; 95 } 96 print(", mask #%lux\n", v&0xFF); 97 v = m->bcsr[3]>>16; 98 print("MPC8xxFADS rev %lud, DB: ", ((v>>4)&8)|((v>>1)&4)|(v&3)); 99 f = (v>>8)&0x3F; 100 switch(f){ 101 default: print("ID#%x", f); break; 102 case 0x00: print("MPC860/821"); break; 103 case 0x01: print("MPC813"); break; 104 case 0x02: print("MPC821"); break; 105 case 0x03: print("MPC823"); break; 106 case 0x20: print("MPC801"); break; 107 case 0x21: print("MPC850"); break; 108 case 0x22: print("MPC860"); break; 109 case 0x23: print("MPC860SAR"); break; 110 case 0x24: print("MPC860T"); break; 111 } 112 print("ADS, rev #%lux\n", (m->bcsr[2]>>16)&7); 113 for(i=0; i<=4; i++) 114 print("BCSR%d: %8.8lux\n", i, m->bcsr[i]); 115 v = m->bcsr[2]; 116 f = (v>>28)&0xF; 117 switch(f){ 118 default: print("Unknown"); break; 119 case 4: print("SM732A2000/SM73228 - 8M SIMM"); break; 120 case 5: print("SM732A1000A/SM73218 - 4M SIMM"); break; 121 case 6: print("MCM29080 - 8M SIMM"); break; 122 case 7: print("MCM29040 - 4M SIMM"); break; 123 case 8: print("MCM29020 - 2M SIMM"); break; 124 } 125 switch((m->bcsr[3]>>20)&7){ 126 default: i = 0; break; 127 case 1: i = 150; break; 128 case 2: i = 120; break; 129 case 3: i = 90; break; 130 } 131 print(" flash, %dns\n", i); 132 f = (v>>23)&0xF; 133 switch(f&3){ 134 case 0: i = 4; break; 135 case 1: i = 32; break; 136 case 2: i = 16; break; 137 case 3: i = 8; break; 138 } 139 print("%dM SIMM, ", i); 140 switch(f>>2){ 141 default: i = 0; break; 142 case 2: i = 70; break; 143 case 3: i = 60; break; 144 } 145 print("%dns\n", i); 146 print("options: #%lux\n", (m->bcsr[2]>>19)&0xF); 147 print("plprcr=%8.8lux sccr=%8.8lux\n", m->iomem->plprcr, m->iomem->sccr); 148 } 149 150 void 151 cpuidprint(void) 152 { 153 int t; 154 155 print("PVR: "); 156 t = getpvr()>>16; 157 switch(t){ 158 case 0x01: print("MPC601"); break; 159 case 0x03: print("MPC603"); break; 160 case 0x04: print("MPC604"); break; 161 case 0x06: print("MPC603e"); break; 162 case 0x07: print("MPC603e-v7"); break; 163 case 0x50: print("MPC8xx"); break; 164 default: print("PowerPC version #%x", t); break; 165 } 166 print(", revision #%lux\n", getpvr()&0xffff); 167 archidprint(); 168 print("%lud MHz system\n", m->cpuhz/MHz); 169 print("\n"); 170 } 171 172 static char* defplan9ini[2] = { 173 /* 860/821 */ 174 "ether0=type=SCC port=1 ea=00108bf12900\r\n" 175 "vgasize=640x480x8\r\n" 176 "kernelpercent=40\r\n" 177 "console=0 lcd\r\nbaud=9600\r\n", 178 179 /* 823 */ 180 "ether0=type=SCC port=2 ea=00108bf12900\r\n" 181 "vgasize=640x480x8\r\n" 182 "kernelpercent=40\r\n" 183 "console=0 lcd\r\nbaud=9600\r\n", 184 }; 185 186 char * 187 archconfig(void) 188 { 189 print("Using default configuration\n"); 190 return defplan9ini[MPCMODEL(m->cputype) == 0x823]; 191 } 192 193 /* 194 * provide value for #r/switch (devrtc.c) 195 */ 196 int 197 archoptionsw(void) 198 { 199 return (m->bcsr[2]>>19)&0xF; /* value of switch DS1 */ 200 } 201 202 /* 203 * invoked by clock.c:/^clockintr 204 */ 205 static void 206 twinkle(void) 207 { 208 if(m->ticks%MS2TK(1000) == 0) 209 m->bcsr[4] ^= DisableLamp; 210 } 211 212 void (*archclocktick)(void) = twinkle; 213 214 /* 215 * for flash.c:/^flashreset 216 * retrieve flash type, virtual base and length and return 0; 217 * return -1 on error (no flash) 218 */ 219 int 220 archflashreset(char *type, void **addr, long *length) 221 { 222 char *t; 223 int mbyte; 224 225 if((m->iomem->memc[0].base & 1) == 0) 226 return -1; /* shouldn't happen */ 227 switch((m->bcsr[2]>>28)&0xF){ 228 default: return -1; /* unknown or not there */ 229 case 4: mbyte=8; t = "SM732x8"; break; 230 case 5: mbyte=4; t = "SM732x8"; break; 231 case 6: mbyte=8; t = "AMD29F0x0"; break; 232 case 7: mbyte=4; t = "AMD29F0x0"; break; 233 case 8: mbyte=2; t = "AMD29F0x0"; break; 234 } 235 strcpy(type, t); 236 *addr = KADDR(FLASHMEM); 237 *length = mbyte*1024*1024; 238 return 0; 239 } 240 241 /* 242 * enable the clocks for the given SCC ether and reveal them to the caller. 243 * do anything else required to prepare the transceiver (eg, set full-duplex, reset loopback). 244 */ 245 int 246 archetherenable(int cpmid, int *rcs, int *tcs) 247 { 248 IMM *io; 249 250 switch(cpmid){ 251 default: 252 /* no other SCCs are wired on the FADS board */ 253 return -1; 254 255 case SCC2ID: /* assume 8xxFADS board with 823DABS */ 256 io = ioplock(); 257 m->bcsr[1] |= DisableIR|DisableRS232b; 258 m->bcsr[1] &= ~DisableEther; 259 io->papar |= SIBIT(6)|SIBIT(5); /* enable CLK2 and CLK3 */ 260 io->padir &= ~(SIBIT(6)|SIBIT(5)); 261 262 /* ETHLOOP etc set in BCSR elsewhere */ 263 *rcs = CLK2; 264 *tcs = CLK3; 265 iopunlock(); 266 break; 267 268 case SCC1ID: /* assume 860/21 development board */ 269 io = ioplock(); 270 m->bcsr[1] |= DisableIR|DisableRS232b; /* TO DO: might not be shared with RS232b */ 271 m->bcsr[1] &= ~DisableEther; 272 io->papar |= SIBIT(6)|SIBIT(7); /* enable CLK2 and CLK1 */ 273 io->padir &= ~(SIBIT(6)|SIBIT(7)); 274 275 /* settings peculiar to 860/821 development board */ 276 io->pcpar &= ~(SIBIT(4)|SIBIT(5)|SIBIT(6)); /* ETHLOOP, TPFULDL~, TPSQEL~ */ 277 io->pcdir |= SIBIT(4)|SIBIT(5)|SIBIT(6); 278 io->pcdat &= ~SIBIT(4); 279 io->pcdat |= SIBIT(5)|SIBIT(6); 280 *rcs = CLK2; 281 *tcs = CLK1; 282 iopunlock(); 283 break; 284 } 285 return 0; 286 } 287 288 void 289 archetherdisable(int id) 290 { 291 USED(id); 292 m->bcsr[1] |= DisableEther|DisableIR|DisableRS232b; 293 } 294 295 /* 296 * do anything extra required to enable the UART on the given CPM port 297 */ 298 void 299 archenableuart(int id, int irda) 300 { 301 switch(id){ 302 case SMC1ID: 303 m->bcsr[1] &= ~DisableRS232a; 304 break; 305 case SCC2ID: 306 m->bcsr[1] |= DisableEther|DisableIR|DisableRS232b; 307 if(irda) 308 m->bcsr[1] &= ~DisableIR; 309 else 310 m->bcsr[1] &= ~DisableRS232b; 311 break; 312 default: 313 /* nothing special */ 314 break; 315 } 316 } 317 318 /* 319 * do anything extra required to disable the UART on the given CPM port 320 */ 321 void 322 archdisableuart(int id) 323 { 324 switch(id){ 325 case SMC1ID: 326 m->bcsr[1] |= DisableRS232a; 327 break; 328 case SCC2ID: 329 m->bcsr[1] |= DisableIR|DisableRS232b; 330 break; 331 default: 332 /* nothing special */ 333 break; 334 } 335 } 336 337 /* 338 * enable/disable the LCD panel's backlight via 339 * York touch panel interface (does no harm without it) 340 */ 341 void 342 archbacklight(int on) 343 { 344 IMM *io; 345 346 delay(2); 347 io = ioplock(); 348 io->papar &= ~SIBIT(4); 349 io->padir |= SIBIT(4); 350 if(on) 351 io->padat |= SIBIT(4); 352 else 353 io->padat &= ~SIBIT(4); 354 iopunlock(); 355 } 356