#define OUTC(addr, val) *(unsigned char *)(addr) = (val)
-
/* sadly, romcc can't quite handle what we want, so we do this ugly thing */
#define drcctl (( volatile unsigned char *)0xfffef010)
#define drcmctl (( volatile unsigned char *)0xfffef012)
#define drccfg (( volatile unsigned char *)0xfffef014)
-#define drcbendadr (( volatile unsigned char *)0xfffef018)
+#define drcbendadr (( volatile unsigned long *)0xfffef018)
#define eccctl (( volatile unsigned char *)0xfffef020)
#define dbctl (( volatile unsigned char *)0xfffef040)
-void
-setupsc520(void){
- volatile unsigned char *cp;
- volatile unsigned short *sp;
- volatile unsigned long *edi;
- volatile unsigned long *par;
-
- /* do this to see if MMCR will start acting right.
- * we suspect you have to do SOMETHING to get things going.
- * I'm really starting to hate this processor.
- */
- /* no, that did not help. I wonder what will?
- * outl(0x800df0cb, 0xfffc);
- */
+void setupsc520(void)
+{
+ volatile unsigned char *cp;
+ volatile unsigned short *sp;
+ volatile unsigned long *edi;
+ /* do this to see if MMCR will start acting right. we suspect
+ * you have to do SOMETHING to get things going. I'm really
+ * starting to hate this processor.
+ */
+
+ /* no, that did not help. I wonder what will?
+ * outl(0x800df0cb, 0xfffc);
+ */
+
+ /* well, this is special! You have to do SHORT writes to the
+ * locations, even though they are CHAR in size and CHAR aligned
+ * and technically, a SHORT write will result in -- yoo ha! --
+ * over writing the next location! Thanks to the u-boot guys
+ * for a reference code I can use. with these short pointers,
+ * it now reliably comes up after power cycle with printk. Ah yi
+ * yi.
+ */
+
/* turn off the write buffer*/
- cp = (unsigned char *)0xfffef040;
- *cp = 0;
+ /* per the note above, make this a short? Let's try it. */
+ sp = (unsigned short *)0xfffef040;
+ *sp = 0;
+
+ /* as per the book: */
+ /* PAR register setup */
+ /* set up the PAR registers as they are on the MSM586SEG */
+ /* moved to auto.c by Stepan, Ron says: */
+ /* NOTE: move this to mainboard.c ASAP */
+ setup_pars();
+
+ /* CPCSF register */
+ sp = (unsigned short *)0xfffefc24;
+ *sp = 0xfe;
+
+ /* ADDDECTL */
+ sp = (unsigned short *)0xfffefc80;
+ *sp = 0x10;
/* byte writes in AMD assembly */
/* we do short anyway, since u-boot does ... */
/* the 0x80 led should now be working*/
outb(0xaa, 0x80);
-
+#if 0
/* wtf are 680 leds ... */
par = (unsigned long *) 0xfffef0c4;
*par = 0x28000680;
/* well? */
outb(0x55, 0x80);
+#endif
-
-/*; set the uart baud rate clocks to the normal 1.8432 MHz.*/
+ /* set the uart baud rate clocks to the normal 1.8432 MHz.*/
+ /* enable interrupts here? Why not? */
cp = (unsigned char *)0xfffefcc0;
- *cp = 4; /* uart 1 clock source */
+ *cp = 4 | 3; /* uart 1 clock source */
cp = (unsigned char *)0xfffefcc4;
- *cp = 4; /* uart 2 clock source */
+ *cp = 4; /* uart 2 clock source */
+
+#if 0
/*; set the interrupt mapping registers.*/
cp = (unsigned char *)0x0fffefd20;
*cp = 0x01;
cp = (unsigned char *)0x0fffefd51;
*cp = 0x02;
-
-/*; "enumerate" the PCI. Mainly set the interrupt bits on the PCnetFast. */
- outl(0xcf8, 0x08000683c);
- outl(0xcfc, 0xc); /* set the interrupt line */
+#endif
-/*; Set the SC520 PCI host bridge to target mode to allow external*/
-/*; bus mastering events*/
+/* Stepan says: This needs to go to the msm586seg code */
+/* "enumerate" the PCI. Mainly set the interrupt bits on the PCnetFast. */
+ outl(0x08000683c, 0xcf8);
+ outl(0xc, 0xcfc); /* set the interrupt line */
- outl(0x0cf8,0x080000004); /*index the status command register on device 0*/
- outl(0xcfc, 0x2); /*set the memory access enable bit*/
+
+ /* Set the SC520 PCI host bridge to target mode to
+ * allow external bus mastering events
+ */
+ /* index the status command register on device 0*/
+ outl(0x080000004, 0x0cf8);
+ outl(0x2, 0xcfc); /*set the memory access enable bit*/
OUTC(0x0fffef072, 1); /* enable req bits in SYSARBMENB */
-
-
-
- /* set up the PAR registers as they are on the MSM586SEG */
- par = (unsigned long *) 0xfffef088;
- *par++ = 0x607c00a0; /*PAR0: PCI:Base 0xa0000; size 0x1f000:*/
- *par++ = 0x480400d8; /*PAR1: GP BUS MEM:CS2:Base 0xd8, size 0x4:*/
- *par++ = 0x340100ea; /*PAR2: GP BUS IO:CS5:Base 0xea, size 0x1:*/
- *par++ = 0x380701f0; /*PAR3: GP BUS IO:CS6:Base 0x1f0, size 0x7:*/
- *par++ = 0x3c0003f6; /*PAR4: GP BUS IO:CS7:Base 0x3f6, size 0x0:*/
- *par++ = 0x35ff0400; /*PAR5: GP BUS IO:CS5:Base 0x400, size 0xff:*/
- *par++ = 0x35ff0600; /*PAR6: GP BUS IO:CS5:Base 0x600, size 0xff:*/
- *par++ = 0x35ff0800; /*PAR7: GP BUS IO:CS5:Base 0x800, size 0xff:*/
- *par++ = 0x35ff0a00; /*PAR8: GP BUS IO:CS5:Base 0xa00, size 0xff:*/
- *par++ = 0x35ff0e00; /*PAR9: GP BUS IO:CS5:Base 0xe00, size 0xff:*/
- *par++ = 0x34fb0104; /*PAR10: GP BUS IO:CS5:Base 0x104, size 0xfb:*/
- *par++ = 0x35af0200; /*PAR11: GP BUS IO:CS5:Base 0x200, size 0xaf:*/
- *par++ = 0x341f03e0; /*PAR12: GP BUS IO:CS5:Base 0x3e0, size 0x1f:*/
- *par++ = 0xe41c00c0; /*PAR13: SDRAM:code:cache:nowrite:Base 0xc0000, size 0x7000:*/
- *par++ = 0x545c00c8; /*PAR14: GP BUS MEM:CS5:Base 0xc8, size 0x5c:*/
-// *par++ = 0x8a020200; /*PAR15: BOOTCS:code:nocache:write:Base 0x2000000, size 0x80000:*/
-
-
}
;
}
+/* looks like we define this now */
+void
+udelay(int microseconds) {
+ sc520_udelay(microseconds);
+}
+
static void dumpram(void){
print_err("ctl "); print_err_hex8(*drcctl); print_err("\r\n");
print_err("bendadr2 "); print_err_hex8(*drcbendadr); print_err("\r\n");
print_err("bendadr3"); print_err_hex8(*drcbendadr); print_err("\r\n");
}
-#ifdef FUCK
+
+/* there is a lot of silliness in the amd code, and it is
+ * causing romcc real headaches, so we're going to be be a little
+ * less silly.
+ * so, the order of ops is:
+ * for i in 3 to 0
+ * see if bank is there.
+ * if we can write a word, and read it back, to hell with paranoia
+ * the bank is there. So write the magic byte, read it back, and
+ * use that to get size, etc. Try to keep things very simple,
+ * so people can actually follow the damned code.
+ */
/* cache is assumed to be disabled */
int sizemem(void)
int rows,banks, cols, i, bank;
unsigned char al;
-
+ volatile unsigned long *lp = (volatile unsigned long *) CACHELINESZ;
+ unsigned long l;
/* initialize dram controller registers */
-
- *dbctl = 0; /* disable write buffer/read-ahead buffer */
+ /* disable write buffer/read-ahead buffer */
+ *dbctl = 0;
+ /* no ecc interrupts of any kind. */
*eccctl = 0;
- *drcmctl = 0x1e; /* Set SDRAM timing for slowest speed. */
+ /* Set SDRAM timing for slowest speed. */
+ *drcmctl = 0x1e;
+
+ /* setup dram register for all banks
+ * with max cols and max banks
+ * this is the oldest trick in the book. You are going to set up for max rows
+ * and cols, then do a write, then see if the data is wrapped to low memory.
+ * you can actually tell by which data gets to which low memory,
+ * exactly how many rows and cols you have.
+ */
+ *drccfg=0xbbbb;
/* setup loop to do 4 external banks starting with bank 3 */
- print_err("sizemem\n");
+ *drcbendadr=0x0ff000000;
+ /* for now, set it up for one loop of bank 0. Just to get it to go at all. */
+ *drcbendadr=0x0ff;
+
+ /* issue a NOP to all DRAMs */
+ /* Setup DRAM control register with Disable refresh,
+ * disable write buffer Test Mode and NOP command select
+ */
+ *drcctl=0x01;
+
+ /* dummy write for NOP to take effect */
+ dummy_write();
+ print_err("NOP\n");
+ /* 100? 200? */
+ udelay(100);
+ print_err("after sc520_udelay\r\n");
+
+ /* issue all banks precharge */
+ *drcctl=0x02;
+ print_err("set *drcctl to 2 \r\n");
+ dummy_write();
+ print_err("PRE\n");
+
+ /* issue 2 auto refreshes to all banks */
+ *drcctl=0x04;
+ dummy_write();
+ print_err("AUTO1\n");
+ dummy_write();
+ print_err("AUTO2\n");
+
+ /* issue LOAD MODE REGISTER command */
+ *drcctl=0x03;
+ dummy_write();
+ print_err("LOAD MODE REG\n");
+ *drcctl=0x04;
+ for (i=0; i<8; i++) /* refresh 8 times */{
+ dummy_write();
+ print_err("dummy write\r\n");
+ }
+ print_err("8 dummy writes\n");
+
+ /* set control register to NORMAL mode */
+ *drcctl=0x00;
+ print_err("normal\n");
+
+ print_err("HI done normal\r\n");
+
+ print_err("sizemem\n");
+ for(bank = 3; bank >= 0; bank--) {
+ print_err("Try to assign to l\r\n");
+ *lp = 0xdeadbeef;
+ print_err("assigned l ... \r\n");
+ if (*lp != 0xdeadbeef) {
+ print_err(" no memory at bank ");
+ // print_err_hex8(bank);
+ // print_err(" value "); print_err_hex32(*lp);
+ print_err("\r\n");
+ // continue;
+ }
+ *drcctl = 2;
+ dummy_write();
+ *drccfg = *drccfg >> 4;
+ l = *drcbendadr;
+ l >>= 8;
+ *drcbendadr = l;
+ print_err("loop around\r\n");
+ *drcctl = 0;
+ dummy_write();
+ }
+#if 0
/* enable last bank and setup ending address
* register for max ram in last bank
*/
*drcbendadr=0x0ff000000;
- /* setup dram register for all banks
- * with max cols and max banks
- */
- *drccfg=0xbbbb;
// dumpram();
goto bad_reinit;
while(1)
print_err("DONE NEXTBANK\r\n");
-}
#endif
-/* note: based on AMD code, but AMD code is BROKEN AFAIK */
+}
-int
-staticmem(void){
- volatile unsigned char *zero = (unsigned char *) 0;
+/* note: based on AMD code*/
+/* This code is known to work on the digital logic board and on the technologic
+ * systems ts5300
+ */
+int staticmem(void)
+{
+ volatile unsigned long *zero = (unsigned long *) CACHELINESZ;
+
/* set up 0x18 .. **/
*drcbendadr = 0x88;
*drcmctl = 0x1e;
/* two autorefreshes */
*drcctl = 4;
*zero = 0;
- print_err("one zero out on refresh\r\n");
+ print_debug("one zero out on refresh\r\n");
*zero = 0;
- print_err("two zero out on refresh\r\n");
+ print_debug("two zero out on refresh\r\n");
/* load mode register */
*drcctl = 3;
*zero = 0;
- print_err("DONE the load mode reg\r\n");
+ print_debug("DONE the load mode reg\r\n");
/* normal mode */
+ *drcctl = 0x0;
+ *zero = 0;
+ print_debug("DONE one last write and then turn on refresh etc\r\n");
*drcctl = 0x18;
*zero = 0;
- print_err("DONE the normal\r\n");
+ print_debug("DONE the normal\r\n");
*zero = 0xdeadbeef;
- print_err(" zero is now "); print_err_hex32(*zero); print_err("\r\n");
+ if (*zero != 0xdeadbeef)
+ print_debug("NO LUCK\r\n");
+ else
+ print_debug("did a store and load ...\r\n");
+ //print_err_hex32(*zero);
+ // print_err(" zero is now "); print_err_hex32(*zero); print_err("\r\n");
}