Apparently I'm not the only one who forgets which way the outb and
[coreboot.git] / src / cpu / amd / sc520 / raminit.c
index e1975b721c0d6c95bb858944a5107de3b8f6c2e9..d20280761d994d9b39736d4973477705c85f919b 100644 (file)
 
 #define OUTC(addr, val) *(unsigned char *)(addr) = (val)
 
-void p4(unsigned char c){
-  //print_err("TRY A TX NIBLE\r\n");
-  __console_tx_nibble(c);
-  return;
-  print_err("now do the other\r\n");
-
-  //  c = c + '0'; 
-  //  if (c > '9')
-  //    c = c + 39;
-  //  __console_tx_byte(c);
-  //print_err("NO!\r\n");
-  //  return;
-  switch(c) {
-  case 0:
-    print_err("0");
-    break;
-  case 1:
-    print_err("1");
-    break;
-  case 2:
-    print_err("2");
-    break;
-  case 3:
-    print_err("3");
-    break;
-  case 4:
-    print_err("4");
-    break;
-  case 5:
-    print_err("5");
-    break;
-  case 6:
-    print_err("6");
-    break;
-  case 7:
-    print_err("7");
-    break;
-  case 8:
-    print_err("8");
-    break;
-  case 9:
-    print_err("9");
-    break;
-  case 0xa:
-    print_err("a");
-    break;
-  case 0xb:
-    print_err("b");
-    break;
-  case 0xc:
-    print_err("c");
-    break;
-  case 0xd:
-    print_err("d");
-    break;
-  case 0xe:
-    print_err("e");
-    break;
-  case 0xf:
-    print_err("f");
-    break;
-  }
-
-}
-
-void p8(unsigned char c) {
-  /*
-  __console_tx_nibble(c>>4);
-  __console_tx_nibble(c&0xf);
-  */
-  p4(c>>4);
-  p4(c&0xf);
-}
-
-void p16(unsigned short s) {
-  p8(s>>16);
-  p8(s);
-}
-
-void p32(unsigned long l) {
-  p16(l>>16);
-  p16(l);
-}
-
-
 /* 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)
@@ -141,65 +56,44 @@ void p32(unsigned long l) {
 #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);
-   */
-  /* 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*/
-  /* 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 */
-       par = (unsigned long *) 0xfffef088;
 
-       /* NOTE: move this to mainboard.c ASAP */
-#if 1
-
-
-       *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:*/
-#else
-       par += 15;
-#endif
-       *par++ = 0x8a020200; /*PAR15: BOOTCS:code:nocache:write:Base 0x2000000, size 0x80000:*/
+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*/
+       /* 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;
 
@@ -259,12 +153,12 @@ setupsc520(void){
        outb(0x55, 0x80);
 #endif
 
-/*; set the uart baud rate clocks to the normal 1.8432 MHz.*/
-/* enable interrupts here? Why not? */
+       /* set the uart baud rate clocks to the normal 1.8432 MHz.*/
+       /* enable interrupts here? Why not? */
        cp = (unsigned char *)0xfffefcc0;
-       *cp = 4 | 3;                                    /* 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.*/
@@ -285,20 +179,21 @@ setupsc520(void){
        
        cp = (unsigned char *)0x0fffefd51;
        *cp = 0x02;
-#endif 
-/*; "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 */
-
-
-
 }
        
 
@@ -367,7 +262,7 @@ static void dumpram(void){
  * causing romcc real headaches, so we're going to be be a little 
  * less silly.
  * so, the order of ops is: 
- * for in 3 to 0
+ * 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 
@@ -384,17 +279,25 @@ int sizemem(void)
        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 */
        *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 */
@@ -407,7 +310,7 @@ int sizemem(void)
        dummy_write();
        print_err("NOP\n");
        /* 100? 200? */
-       //sc520_udelay(100);
+       udelay(100);
        print_err("after sc520_udelay\r\n");
 
        /* issue all banks precharge */
@@ -701,11 +604,14 @@ bad_ram:
 #endif
 }      
 
-/* note: based on AMD code, but AMD code is BROKEN AFAIK */
-/* this does now work worth shit. */
-int
-staticmem(void){
-  volatile unsigned long *zero = (unsigned long *) CACHELINESZ;
+/* 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;
@@ -722,28 +628,27 @@ staticmem(void){
        /* 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_err("DONE one last write and then turn on refresh etc\n");
+       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;
        if (*zero != 0xdeadbeef) 
-         print_err("NO LUCK\r\n");
+         print_debug("NO LUCK\r\n");
        else
-         print_err("did a stor and load ...\r\n");
-       //      p32(*zero);
-       print_err_hex32(*zero);
+         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");
 }