Revision: linuxbios@linuxbios.org--devel/freebios--devel--2.0--patch-23
[coreboot.git] / src / cpu / amd / sc520 / raminit.c
1
2 /*
3  *
4  *
5  */
6
7 #define DRCCTL        *(char*)0x0fffef010  // DRAM control register
8 #define DRCTMCTL      *(char*)0x0fffef012  // DRAM timing control register
9 #define DRCCFG        *(char*)0x0fffef014  // DRAM bank configuration register
10 #define DRCBENDADR    *(char*)0x0fffef018  // DRAM bank ending address register
11 #define ECCCTL        *(char*)0x0fffef020  // DRAM ECC control register
12 #define DBCTL         *(char*)0x0fffef040  // DRAM buffer control register
13
14 #define CACHELINESZ   0x00000010  //  size of our cache line (read buffer)
15
16 #define COL11_ADR  *(unsigned int *)0x0e001e00 // 11 col addrs
17 #define COL10_ADR  *(unsigned int *)0x0e000e00 // 10 col addrs
18 #define COL09_ADR  *(unsigned int *)0x0e000600 //  9 col addrs
19 #define COL08_ADR  *(unsigned int *)0x0e000200 //  8 col addrs
20
21 #define ROW14_ADR  *(unsigned int *)0x0f000000 // 14 row addrs
22 #define ROW13_ADR  *(unsigned int *)0x07000000 // 13 row addrs
23 #define ROW12_ADR  *(unsigned int *)0x03000000 // 12 row addrs
24 #define ROW11_ADR  *(unsigned int *)0x01000000 // 11 row addrs/also bank switch
25 #define ROW10_ADR  *(unsigned int *)0x00000000 // 10 row addrs/also bank switch
26
27 #define COL11_DATA 0x0b0b0b0b   //  11 col addrs
28 #define COL10_DATA 0x0a0a0a0a   //  10 col data
29 #define COL09_DATA 0x09090909   //   9 col data
30 #define COL08_DATA 0x08080808   //   8 col data
31 #define ROW14_DATA 0x3f3f3f3f   //  14 row data (MASK)
32 #define ROW13_DATA 0x1f1f1f1f   //  13 row data (MASK)
33 #define ROW12_DATA 0x0f0f0f0f   //  12 row data (MASK)
34 #define ROW11_DATA 0x07070707   //  11 row data/also bank switch (MASK)
35 #define ROW10_DATA 0xaaaaaaaa   //  10 row data/also bank switch (MASK)
36
37 #define dummy_write()   *(short *)CACHELINESZ=0x1010
38
39 int nextbank(int bank)
40 {
41         int rows,banks;
42         
43 start:
44         /* write col 11 wrap adr */
45         COL11_ADR=COL11_DATA;
46         if(COL11_ADR!=COL11_DATA)
47                 goto bad_ram;
48
49         /* write col 10 wrap adr */
50         COL10_ADR=COL10_DATA;
51         if(COL10_ADR!=COL10_DATA)
52                 goto bad_ram;
53
54         /* write col 9 wrap adr */
55         COL9_ADR=COL9_DATA;
56         if(COL9_ADR!=COL9_DATA)
57                 goto bad_ram;
58
59         /* write col 8 wrap adr */
60         COL8_ADR=COL8_DATA;
61         if(COL8_ADR!=COL8_DATA)
62                 goto bad_ram;
63
64         /* write row 14 wrap adr */
65         ROW14_ADR=ROW14_DATA;
66         if(ROW14_ADR!=ROW14_DATA)
67                 goto bad_ram;
68
69         /* write row 13 wrap adr */
70         ROW13_ADR=ROW13_DATA;
71         if(ROW13_ADR!=ROW13_DATA)
72                 goto bad_ram;
73
74         /* write row 12 wrap adr */
75         ROW12_ADR=ROW12_DATA;
76         if(ROW12_ADR!=ROW12_DATA)
77                 goto bad_ram;
78
79         /* write row 11 wrap adr */
80         ROW11_ADR=ROW11_DATA;
81         if(ROW11_ADR!=ROW11_DATA)
82                 goto bad_ram;
83
84         /* write row 10 wrap adr */
85         ROW10_ADR=ROW10_DATA;
86         if(ROW10_ADR!=ROW10_DATA)
87                 goto bad_ram;
88
89 /*
90  * read data @ row 12 wrap adr to determine # banks,
91  *  and read data @ row 14 wrap adr to determine # rows.
92  *  if data @ row 12 wrap adr is not AA, 11 or 12 we have bad RAM.
93  * if data @ row 12 wrap == AA, we only have 2 banks, NOT 4
94  * if data @ row 12 wrap == 11 or 12, we have 4 banks
95  */
96
97         banks=2;
98         if (ROW12_ADDR != ROW10_DATA) {
99                 banks=4;
100                 if(ROW12_ADDR != ROW11_DATA) {
101                         if(ROW12_ADDR != ROW12_DATA)
102                                 goto bad_ram;
103                 }
104         }
105
106         /* validate row mask */
107         i=ROW14_ADDR;
108         if (i<ROW11_DATA)
109                 goto bad_ram;
110         if (i>ROW14_DATA)
111                 goto bad_ram;
112         /* verify all 4 bytes of dword same */
113         if(i&0xffff!=(i>>16)&0xffff)
114                 goto bad_ram;
115         if(i&0xff!=(i>>8)&0xff)
116                 goto bad_ram;
117         
118         
119         /* validate column data */
120         i=COL11_ADDR;
121         if(i<COL8_DATA)
122                 goto bad_ram;
123         if (i>COL11_DATA)
124                 goto bad_ram;
125         /* verify all 4 bytes of dword same */
126         if(i&0xffff!=(i>>16)&0xffff)
127                 goto bad_ram;
128         if(i&0xff!=(i>>8)&0xff)
129                 goto bad_ram;
130         
131         if(banks==4)
132                 i+=8; /* <-- i holds merged value */
133         
134         /* fix ending addr mask*/
135         /*FIXME*/
136         ending_adr=0xff;
137
138 bad_reint:
139         /* issue all banks recharge */
140         DRCCTL=0x02;
141         dummy_write();
142
143         /* update ending address register */
144         *(DRCBENDADR+xxxx)=ending_adr;
145         
146         /* update config register */
147         DRCCFG=DRCCFG&YYY|ZZZZ;
148
149         if(bank!=0) {
150                 bank--;
151                 *(&DRCBENDADR+XXYYXX)=0xff;
152                 goto start;
153         }
154
155         /* set control register to NORMAL mode */
156         DRCCTL=0x00;
157         dummy_write();
158         return bank;
159         
160 bad_ram:
161         printk_error("bad ram!\r\n");
162 }
163
164 /* cache is assumed to be disabled */
165 int sizemem(void)
166 {
167         int i;
168         /* initialize dram controller registers */
169
170         DBCTL=0; /* disable write buffer/read-ahead buffer */
171         ECCCTL=0; /* disable ECC */
172         DRCTMCTL=0x1e; /* Set SDRAM timing for slowest speed. */
173
174         /* setup loop to do 4 external banks starting with bank 3 */
175
176         /* enable last bank and setup ending address 
177          * register for max ram in last bank
178          */
179         DRCBENDADR=0x0ff000000;
180         /* setup dram register for all banks
181          * with max cols and max banks
182          */
183         DRCCFG=0xbbbb;
184
185         /* issue a NOP to all DRAMs */
186
187         /* Asetup DRAM control register with Disable refresh,
188          * disable write buffer Test Mode and NOP command select
189          */
190         DRCCTL=0x01;
191
192         /* dummy write for NOP to take effect */
193         dummy_write();
194
195         /* 100? 200? */
196         udelay(100);
197
198         /* issue all banks precharge */
199         DRCCTL=0x02;
200         dummy_write();
201
202         /* issue 2 auto refreshes to all banks */
203         DRCCTL=0x04;
204         dummy_write();
205         dummy_write();
206
207         /* issue LOAD MODE REGISTER command */
208         DRCCTL=0x03;
209         dummy_write();
210
211         DRCCTL=0x04;
212         for (i=0; i<8; i++) /* refresh 8 times */
213                 dummy_write();
214
215         /* set control register to NORMAL mode */
216         DRCCTL=0x00;
217
218         nextbank(3);
219
220 }