1 /* this setupcpu function comes from: */
2 /*==============================================================================*/
3 /* FILE : start16.asm*/
5 /* DESC : A 16 bit mode assembly language startup program, intended for*/
6 /* use with on Aspen SC520 platforms.*/
8 /* 11/16/2000 Added support for the NetSC520*/
9 /* 12/28/2000 Modified to boot linux image*/
11 /* =============================================================================*/
13 /* Copyright 2000 Advanced Micro Devices, Inc. */
15 /* This software is the property of Advanced Micro Devices, Inc (AMD) which */
16 /* specifically grants the user the right to modify, use and distribute this */
17 /* software provided this COPYRIGHT NOTICE is not removed or altered. All */
18 /* other rights are reserved by AMD. */
20 /* THE MATERIALS ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY */
21 /* OF ANY KIND INCLUDING WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT OF */
22 /* THIRD-PARTY INTELLECTUAL PROPERTY, OR FITNESS FOR ANY PARTICULAR PURPOSE.*/
23 /* IN NO EVENT SHALL AMD OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER*/
24 /* (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS*/
25 /* INTERRUPTION, LOSS OF INFORMATION) ARISING OUT OF THE USE OF OR INABILITY*/
26 /* TO USE THE MATERIALS, EVEN IF AMD HAS BEEN ADVISED OF THE POSSIBILITY OF*/
27 /* SUCH DAMAGES. BECAUSE SOME JURSIDICTIONS PROHIBIT THE EXCLUSION OR*/
28 /* LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE*/
29 /* LIMITATION MAY NOT APPLY TO YOU.*/
31 /* AMD does not assume any responsibility for any errors that may appear in*/
32 /* the Materials nor any responsibility to support or update the Materials.*/
33 /* AMD retains the right to make changes to its test specifications at any*/
34 /* time, without notice.*/
36 /* So that all may benefit from your experience, please report any problems */
37 /* or suggestions about this software back to AMD. Please include your name, */
38 /* company, telephone number, AMD product requiring support and question or */
39 /* problem encountered. */
41 /* Advanced Micro Devices, Inc. Worldwide support and contact */
42 /* Embedded Processor Division information available at: */
43 /* Systems Engineering epd.support@amd.com*/
44 /* 5204 E. Ben White Blvd. -or-*/
45 /* Austin, TX 78741 http://www.amd.com/html/support/techsup.html*/
46 /* ============================================================================*/
48 #define OUTC(addr, val) *(unsigned char *)(addr) = (val)
58 /* turn off the write buffer*/
59 cp = (unsigned char *)0xfffef040;
62 /*set the GP CS offset*/
63 sp = (unsigned short *)0xfffefc08;
65 /*set the GP CS width*/
66 sp = (unsigned short *)0xfffefc09;
68 /*set the GP CS width*/
69 sp = (unsigned short *)0xfffefc0a;
71 /*set the RD pulse width*/
72 sp = (unsigned short *)0xfffefc0b;
74 /*set the GP RD offse*/
75 sp = (unsigned short *)0xfffefc0c;
77 /*set the GP WR pulse width*/
78 sp = (unsigned short *)0xfffefc0d;
80 /*set the GP WR offset*/
81 sp = (unsigned short *)0xfffefc0e;
83 /* set up the GP IO pins*/
84 /*set the GPIO directionreg*/
85 sp = (unsigned short *)0xfffefc2c;
87 /*set the GPIO directionreg*/
88 sp = (unsigned short *)0xfffefc2a;
90 /*set the GPIO pin function 31-16 reg*/
91 sp = (unsigned short *)0xfffefc22;
93 /*set the GPIO pin function 15-0 reg*/
94 sp = (unsigned short *)0xfffefc20;
99 ; set the PIO regs correctly.
100 /*set the GPIO16-31 direction reg*/
101 sp = (unsigned short *)0xfffefc2c;
103 /*set the PIODIR15_0 direction reg*/
104 sp = (unsigned short *)0xfffefc2a;
106 /*set the PIOPFS31_16 direction reg*/
107 sp = (unsigned short *)0xfffefc22;
109 /*set the PIOPFS15_0 direction reg*/
110 sp = (unsigned short *)0xfffefc20;
112 /*set the PIODATA15_0 reg*/
113 sp = (unsigned short *)0x0xfffefc30;
115 /*set the CSPFS reg*/
116 sp = (unsigned short *)0xfffefc24;
119 ; The NetSC520 uses PIOs 16-23 for LEDs instead of port 80
120 ; output a 1 to the leds
121 /*set the GPIO16-31 direction reg*/
122 sp = (unsigned short *)0xfffefc32;
127 /* setup for the CDP*/
128 /*set the GPIO directionreg*/
129 sp = (unsigned short *)0xfffefc2c;
131 /*set the GPIO directionreg*/
132 sp = (unsigned short *)0xfffefc2a;
134 /*set the GPIO pin function 31-16 reg*/
135 sp = (unsigned short *)0xfffefc22;
137 /*set the GPIO pin function 15-0 reg*/
138 sp = (unsigned short *)0xfffefc20;
140 /* the 0x80 led should now be working*/
143 ; set up a PAR to allow access to the 680 leds
144 ; WriteMMCR( 0xc4,0x28000680); // PAR15
146 /*set PAR 15 for access to led 680*/
147 /* skip hairy pci hack for now *
148 sp = (unsigned short *)0xfffef0c4;
151 *sp = 0x02; ; output a 2 to led 680
154 /*; set the uart baud rate clocks to the normal 1.8432 MHz.*/
155 cp = (unsigned char *)0xfffefcc0;
156 *cp = 4; /* uart 1 clock source */
157 cp = (unsigned char *)0xfffefcc4;
158 *cp = 4; /* uart 2 clock source */
159 /*; set the interrupt mapping registers.*/
160 cp = (unsigned char *)0x0fffefd20;
163 cp = (unsigned char *)0x0fffefd28;
166 cp = (unsigned char *)0x0fffefd29;
169 cp = (unsigned char *)0x0fffefd30;
172 cp = (unsigned char *)0x0fffefd43;
175 cp = (unsigned char *)0x0fffefd51;
178 /*; "enumerate" the PCI. Mainly set the interrupt bits on the PCnetFast. */
179 outl(0xcf8, 0x08000683c);
180 outl(0xcfc, 0xc); /* set the interrupt line */
182 /*; Set the SC520 PCI host bridge to target mode to allow external*/
183 /*; bus mastering events*/
185 outl(0x0cf8,0x080000004); /*index the status command register on device 0*/
186 outl(0xcfc, 0x2); /*set the memory access enable bit*/
187 OUTC(0x0fffef072, 1); /* enable req bits in SYSARBMENB */
191 /* set up the PAR registers as they are on the MSM586SEG */
192 par = (unsigned long *) 0xfffef080;
193 *par++ = 0x607c00a0; /*PAR0: PCI:Base 0xa0000; size 0x1f000:*/
194 *par++ = 0x480400d8; /*PAR1: GP BUS MEM:CS2:Base 0xd8, size 0x4:*/
195 *par++ = 0x340100ea; /*PAR2: GP BUS IO:CS5:Base 0xea, size 0x1:*/
196 *par++ = 0x380701f0; /*PAR3: GP BUS IO:CS6:Base 0x1f0, size 0x7:*/
197 *par++ = 0x3c0003f6; /*PAR4: GP BUS IO:CS7:Base 0x3f6, size 0x0:*/
198 *par++ = 0x35ff0400; /*PAR5: GP BUS IO:CS5:Base 0x400, size 0xff:*/
199 *par++ = 0x35ff0600; /*PAR6: GP BUS IO:CS5:Base 0x600, size 0xff:*/
200 *par++ = 0x35ff0800; /*PAR7: GP BUS IO:CS5:Base 0x800, size 0xff:*/
201 *par++ = 0x35ff0a00; /*PAR8: GP BUS IO:CS5:Base 0xa00, size 0xff:*/
202 *par++ = 0x35ff0e00; /*PAR9: GP BUS IO:CS5:Base 0xe00, size 0xff:*/
203 *par++ = 0x34fb0104; /*PAR10: GP BUS IO:CS5:Base 0x104, size 0xfb:*/
204 *par++ = 0x35af0200; /*PAR11: GP BUS IO:CS5:Base 0x200, size 0xaf:*/
205 *par++ = 0x341f03e0; /*PAR12: GP BUS IO:CS5:Base 0x3e0, size 0x1f:*/
206 *par++ = 0xe41c00c0; /*PAR13: SDRAM:code:cache:nowrite:Base 0xc0000, size 0x7000:*/
207 *par++ = 0x545c00c8; /*PAR14: GP BUS MEM:CS5:Base 0xc8, size 0x5c:*/
208 *par++ = 0x8a020200; /*PAR15: BOOTCS:code:nocache:write:Base 0x2000000, size 0x80000:*/
219 #define DRCCTL *(char*)0x0fffef010 /* DRAM control register*/
220 #define DRCTMCTL *(char*)0x0fffef012 /* DRAM timing control register*/
221 #define DRCCFG *(char*)0x0fffef014 /* DRAM bank configuration register*/
222 #define DRCBENDADR *(char*)0x0fffef018 /* DRAM bank ending address register*/
223 #define ECCCTL *(char*)0x0fffef020 /* DRAM ECC control register*/
224 #define DBCTL *(char*)0x0fffef040 /* DRAM buffer control register*/
226 #define CACHELINESZ 0x00000010 /* size of our cache line (read buffer)*/
228 #define COL11_ADR *(unsigned int *)0x0e001e00 /* 11 col addrs*/
229 #define COL10_ADR *(unsigned int *)0x0e000e00 /* 10 col addrs*/
230 #define COL09_ADR *(unsigned int *)0x0e000600 /* 9 col addrs*/
231 #define COL08_ADR *(unsigned int *)0x0e000200 /* 8 col addrs*/
233 #define ROW14_ADR *(unsigned int *)0x0f000000 /* 14 row addrs*/
234 #define ROW13_ADR *(unsigned int *)0x07000000 /* 13 row addrs*/
235 #define ROW12_ADR *(unsigned int *)0x03000000 /* 12 row addrs*/
236 #define ROW11_ADR *(unsigned int *)0x01000000 /* 11 row addrs/also bank switch*/
237 #define ROW10_ADR *(unsigned int *)0x00000000 /* 10 row addrs/also bank switch*/
239 #define COL11_DATA 0x0b0b0b0b /* 11 col addrs*/
240 #define COL10_DATA 0x0a0a0a0a /* 10 col data*/
241 #define COL09_DATA 0x09090909 /* 9 col data*/
242 #define COL08_DATA 0x08080808 /* 8 col data*/
243 #define ROW14_DATA 0x3f3f3f3f /* 14 row data (MASK)*/
244 #define ROW13_DATA 0x1f1f1f1f /* 13 row data (MASK)*/
245 #define ROW12_DATA 0x0f0f0f0f /* 12 row data (MASK)*/
246 #define ROW11_DATA 0x07070707 /* 11 row data/also bank switch (MASK)*/
247 #define ROW10_DATA 0xaaaaaaaa /* 10 row data/also bank switch (MASK)*/
249 #define dummy_write() *(short *)CACHELINESZ=0x1010
251 void udelay(int microseconds) {
253 for(x = 0; x < 1000; x++)
257 int nextbank(int bank)
259 int rows,banks, i, ending_adr;
262 /* write col 11 wrap adr */
263 COL11_ADR=COL11_DATA;
264 if(COL11_ADR!=COL11_DATA)
267 /* write col 10 wrap adr */
268 COL10_ADR=COL10_DATA;
269 if(COL10_ADR!=COL10_DATA)
272 /* write col 9 wrap adr */
273 COL09_ADR=COL09_DATA;
274 if(COL09_ADR!=COL09_DATA)
277 /* write col 8 wrap adr */
278 COL08_ADR=COL08_DATA;
279 if(COL08_ADR!=COL08_DATA)
282 /* write row 14 wrap adr */
283 ROW14_ADR=ROW14_DATA;
284 if(ROW14_ADR!=ROW14_DATA)
287 /* write row 13 wrap adr */
288 ROW13_ADR=ROW13_DATA;
289 if(ROW13_ADR!=ROW13_DATA)
292 /* write row 12 wrap adr */
293 ROW12_ADR=ROW12_DATA;
294 if(ROW12_ADR!=ROW12_DATA)
297 /* write row 11 wrap adr */
298 ROW11_ADR=ROW11_DATA;
299 if(ROW11_ADR!=ROW11_DATA)
302 /* write row 10 wrap adr */
303 ROW10_ADR=ROW10_DATA;
304 if(ROW10_ADR!=ROW10_DATA)
308 * read data @ row 12 wrap adr to determine # banks,
309 * and read data @ row 14 wrap adr to determine # rows.
310 * if data @ row 12 wrap adr is not AA, 11 or 12 we have bad RAM.
311 * if data @ row 12 wrap == AA, we only have 2 banks, NOT 4
312 * if data @ row 12 wrap == 11 or 12, we have 4 banks
316 if (ROW12_ADR != ROW10_DATA) {
318 if(ROW12_ADR != ROW11_DATA) {
319 if(ROW12_ADR != ROW12_DATA)
324 /* validate row mask */
330 /* verify all 4 bytes of dword same */
331 if(i&0xffff!=(i>>16)&0xffff)
333 if(i&0xff!=(i>>8)&0xff)
337 /* validate column data */
343 /* verify all 4 bytes of dword same */
344 if(i&0xffff!=(i>>16)&0xffff)
346 if(i&0xff!=(i>>8)&0xff)
350 i+=8; /* <-- i holds merged value */
352 /* fix ending addr mask*/
357 /* issue all banks recharge */
361 /* update ending address register */
362 #warning FIX ME NOW I AM BUSTED
363 // *(DRCBENDADR+0)=ending_adr;
365 /* update config register */
366 // DRCCFG=DRCCFG&YYY|ZZZZ;
370 //*(&DRCBENDADR+XXYYXX)=0xff;
374 /* set control register to NORMAL mode */
380 print_info("bad ram!\r\n");
383 /* cache is assumed to be disabled */
387 /* initialize dram controller registers */
389 DBCTL=0; /* disable write buffer/read-ahead buffer */
390 ECCCTL=0; /* disable ECC */
391 DRCTMCTL=0x1e; /* Set SDRAM timing for slowest speed. */
393 /* setup loop to do 4 external banks starting with bank 3 */
395 /* enable last bank and setup ending address
396 * register for max ram in last bank
398 DRCBENDADR=0x0ff000000;
399 /* setup dram register for all banks
400 * with max cols and max banks
404 /* issue a NOP to all DRAMs */
406 /* Asetup DRAM control register with Disable refresh,
407 * disable write buffer Test Mode and NOP command select
411 /* dummy write for NOP to take effect */
417 /* issue all banks precharge */
421 /* issue 2 auto refreshes to all banks */
426 /* issue LOAD MODE REGISTER command */
431 for (i=0; i<8; i++) /* refresh 8 times */
434 /* set control register to NORMAL mode */