diff options
author | arch import user (historical) <svn@openbios.org> | 2005-07-06 17:03:03 +0000 |
---|---|---|
committer | arch import user (historical) <svn@openbios.org> | 2005-07-06 17:03:03 +0000 |
commit | 0b78ea7a28b4c6c703a10138cc3b6596854fff6f (patch) | |
tree | 0850b021b968d4f1c4a4ea4db260777bd973f58c /src/cpu/amd | |
parent | 4a39e0b67ce13f63ebf23282f7b8f1ae1e803d01 (diff) |
Revision: linuxbios@linuxbios.org--devel/freebios--devel--2.0--patch-23
Creator: Ronald G. Minnich <rminnich@lanl.gov>
add in stepan's raminit code for the sc520
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1939 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src/cpu/amd')
-rw-r--r-- | src/cpu/amd/sc520/raminit.c | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/src/cpu/amd/sc520/raminit.c b/src/cpu/amd/sc520/raminit.c index 8b13789179..b7bf629348 100644 --- a/src/cpu/amd/sc520/raminit.c +++ b/src/cpu/amd/sc520/raminit.c @@ -1 +1,220 @@ +/* + * + * + */ + +#define DRCCTL *(char*)0x0fffef010 // DRAM control register +#define DRCTMCTL *(char*)0x0fffef012 // DRAM timing control register +#define DRCCFG *(char*)0x0fffef014 // DRAM bank configuration register +#define DRCBENDADR *(char*)0x0fffef018 // DRAM bank ending address register +#define ECCCTL *(char*)0x0fffef020 // DRAM ECC control register +#define DBCTL *(char*)0x0fffef040 // DRAM buffer control register + +#define CACHELINESZ 0x00000010 // size of our cache line (read buffer) + +#define COL11_ADR *(unsigned int *)0x0e001e00 // 11 col addrs +#define COL10_ADR *(unsigned int *)0x0e000e00 // 10 col addrs +#define COL09_ADR *(unsigned int *)0x0e000600 // 9 col addrs +#define COL08_ADR *(unsigned int *)0x0e000200 // 8 col addrs + +#define ROW14_ADR *(unsigned int *)0x0f000000 // 14 row addrs +#define ROW13_ADR *(unsigned int *)0x07000000 // 13 row addrs +#define ROW12_ADR *(unsigned int *)0x03000000 // 12 row addrs +#define ROW11_ADR *(unsigned int *)0x01000000 // 11 row addrs/also bank switch +#define ROW10_ADR *(unsigned int *)0x00000000 // 10 row addrs/also bank switch + +#define COL11_DATA 0x0b0b0b0b // 11 col addrs +#define COL10_DATA 0x0a0a0a0a // 10 col data +#define COL09_DATA 0x09090909 // 9 col data +#define COL08_DATA 0x08080808 // 8 col data +#define ROW14_DATA 0x3f3f3f3f // 14 row data (MASK) +#define ROW13_DATA 0x1f1f1f1f // 13 row data (MASK) +#define ROW12_DATA 0x0f0f0f0f // 12 row data (MASK) +#define ROW11_DATA 0x07070707 // 11 row data/also bank switch (MASK) +#define ROW10_DATA 0xaaaaaaaa // 10 row data/also bank switch (MASK) + +#define dummy_write() *(short *)CACHELINESZ=0x1010 + +int nextbank(int bank) +{ + int rows,banks; + +start: + /* write col 11 wrap adr */ + COL11_ADR=COL11_DATA; + if(COL11_ADR!=COL11_DATA) + goto bad_ram; + + /* write col 10 wrap adr */ + COL10_ADR=COL10_DATA; + if(COL10_ADR!=COL10_DATA) + goto bad_ram; + + /* write col 9 wrap adr */ + COL9_ADR=COL9_DATA; + if(COL9_ADR!=COL9_DATA) + goto bad_ram; + + /* write col 8 wrap adr */ + COL8_ADR=COL8_DATA; + if(COL8_ADR!=COL8_DATA) + goto bad_ram; + + /* write row 14 wrap adr */ + ROW14_ADR=ROW14_DATA; + if(ROW14_ADR!=ROW14_DATA) + goto bad_ram; + + /* write row 13 wrap adr */ + ROW13_ADR=ROW13_DATA; + if(ROW13_ADR!=ROW13_DATA) + goto bad_ram; + + /* write row 12 wrap adr */ + ROW12_ADR=ROW12_DATA; + if(ROW12_ADR!=ROW12_DATA) + goto bad_ram; + + /* write row 11 wrap adr */ + ROW11_ADR=ROW11_DATA; + if(ROW11_ADR!=ROW11_DATA) + goto bad_ram; + + /* write row 10 wrap adr */ + ROW10_ADR=ROW10_DATA; + if(ROW10_ADR!=ROW10_DATA) + goto bad_ram; + +/* + * read data @ row 12 wrap adr to determine # banks, + * and read data @ row 14 wrap adr to determine # rows. + * if data @ row 12 wrap adr is not AA, 11 or 12 we have bad RAM. + * if data @ row 12 wrap == AA, we only have 2 banks, NOT 4 + * if data @ row 12 wrap == 11 or 12, we have 4 banks + */ + + banks=2; + if (ROW12_ADDR != ROW10_DATA) { + banks=4; + if(ROW12_ADDR != ROW11_DATA) { + if(ROW12_ADDR != ROW12_DATA) + goto bad_ram; + } + } + + /* validate row mask */ + i=ROW14_ADDR; + if (i<ROW11_DATA) + goto bad_ram; + if (i>ROW14_DATA) + goto bad_ram; + /* verify all 4 bytes of dword same */ + if(i&0xffff!=(i>>16)&0xffff) + goto bad_ram; + if(i&0xff!=(i>>8)&0xff) + goto bad_ram; + + + /* validate column data */ + i=COL11_ADDR; + if(i<COL8_DATA) + goto bad_ram; + if (i>COL11_DATA) + goto bad_ram; + /* verify all 4 bytes of dword same */ + if(i&0xffff!=(i>>16)&0xffff) + goto bad_ram; + if(i&0xff!=(i>>8)&0xff) + goto bad_ram; + + if(banks==4) + i+=8; /* <-- i holds merged value */ + + /* fix ending addr mask*/ + /*FIXME*/ + ending_adr=0xff; + +bad_reint: + /* issue all banks recharge */ + DRCCTL=0x02; + dummy_write(); + + /* update ending address register */ + *(DRCBENDADR+xxxx)=ending_adr; + + /* update config register */ + DRCCFG=DRCCFG&YYY|ZZZZ; + + if(bank!=0) { + bank--; + *(&DRCBENDADR+XXYYXX)=0xff; + goto start; + } + + /* set control register to NORMAL mode */ + DRCCTL=0x00; + dummy_write(); + return bank; + +bad_ram: + printk_error("bad ram!\r\n"); +} + +/* cache is assumed to be disabled */ +int sizemem(void) +{ + int i; + /* initialize dram controller registers */ + + DBCTL=0; /* disable write buffer/read-ahead buffer */ + ECCCTL=0; /* disable ECC */ + DRCTMCTL=0x1e; /* Set SDRAM timing for slowest speed. */ + + /* setup loop to do 4 external banks starting with bank 3 */ + + /* 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; + + /* issue a NOP to all DRAMs */ + + /* Asetup 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(); + + /* 100? 200? */ + udelay(100); + + /* issue all banks precharge */ + DRCCTL=0x02; + dummy_write(); + + /* issue 2 auto refreshes to all banks */ + DRCCTL=0x04; + dummy_write(); + dummy_write(); + + /* issue LOAD MODE REGISTER command */ + DRCCTL=0x03; + dummy_write(); + + DRCCTL=0x04; + for (i=0; i<8; i++) /* refresh 8 times */ + dummy_write(); + + /* set control register to NORMAL mode */ + DRCCTL=0x00; + + nextbank(3); + +} |