]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/i386/cpu/sc520/sc520_asm.S
MX31: Added support for the Casio COM57H5M10XRC to QONG
[karo-tx-uboot.git] / arch / i386 / cpu / sc520 / sc520_asm.S
1 /*
2  * (C) Copyright 2002
3  * Daniel Engström, Omicron Ceti AB <daniel@omicron.se>.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 /* This file is largely based on code obtned from AMD. AMD's original
25  * copyright is included below
26  */
27
28 /*
29  *  =============================================================================
30  *
31  *   Copyright 1999 Advanced Micro Devices, Inc.
32  *
33  *  This software is the property of Advanced Micro Devices, Inc  (AMD)  which
34  *  specifically grants the user the right to modify, use and distribute this
35  *  software provided this COPYRIGHT NOTICE is not removed or altered.  All
36  *  other rights are reserved by AMD.
37  *
38  *  THE MATERIALS ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY
39  *  OF ANY KIND INCLUDING WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT OF
40  *  THIRD-PARTY INTELLECTUAL PROPERTY, OR FITNESS FOR ANY PARTICULAR PURPOSE.
41  *  IN NO EVENT SHALL AMD OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER
42  *  (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS
43  *  INTERRUPTION, LOSS OF INFORMAITON) ARISING OUT OF THE USE OF OR INABILITY
44  *  TO USE THE MATERIALS, EVEN IF AMD HAS BEEN ADVISED OF THE POSSIBILITY OF
45  *  SUCH DAMAGES.  BECAUSE SOME JURSIDICTIONS PROHIBIT THE EXCLUSION OR
46  *  LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE
47  *  LIMITATION MAY NOT APPLY TO YOU.
48  *
49  *  AMD does not assume any responsibility for any errors that may appear in
50  *  the Materials nor any responsibility to support or update the Materials.
51  *  AMD retains the right to make changes to its test specifications at any
52  *  time, without notice.
53  *
54  *  So that all may benefit from your experience, please report  any  problems
55  *  or suggestions about this software back to AMD.  Please include your name,
56  *  company,  telephone number,  AMD product requiring support and question or
57  *  problem encountered.
58  *
59  *  Advanced Micro Devices, Inc.         Worldwide support and contact
60  *  Embedded Processor Division            information available at:
61  *  Systems Engineering                       epd.support@amd.com
62  *  5204 E. Ben White Blvd.                          -or-
63  *  Austin, TX 78741                http://www.amd.com/html/support/techsup.html
64  *  ============================================================================
65  */
66
67
68 /*******************************************************************************
69  *       AUTHOR      : Buddy Fey - Original.
70  *******************************************************************************
71  */
72
73
74 /*******************************************************************************
75  *       FUNCTIONAL DESCRIPTION:
76  * This routine is called to autodetect the geometry of the DRAM.
77  *
78  * This routine is called to determine the number of column bits for the DRAM
79  * devices in this external bank. This routine assumes that the external bank
80  * has been configured for an 11-bit column and for 4 internal banks. This gives
81  * us the maximum address reach in memory. By writing a test value to the max
82  * address and locating where it aliases to, we can determine the number of valid
83  * column bits.
84  *
85  * This routine is called to determine the number of internal banks each DRAM
86  * device has. The external bank (under test) is configured for maximum reach
87  * with 11-bit columns and 4 internal banks. This routine will write to a max
88  * address (BA1 and BA0 = 1) and then read from an address with BA1=0 to see if
89  * that column is a "don't care". If BA1 does not affect write/read of data,
90  * then this device has only 2 internal banks.
91  *
92  * This routine is called to determine the ending address for this external
93  * bank of SDRAM. We write to a max address with a data value and then disable
94  * row address bits looking for "don't care" locations. Each "don't care" bit
95  * represents a dividing of the maximum density (128M) by 2. By dividing the
96  * maximum of 32 4M chunks in an external bank down by all the "don't care" bits
97  * determined during sizing, we set the proper density.
98  *
99  * WARNINGS.
100  * bp must be preserved because it is used for return linkage.
101  *
102  * EXIT
103  * nothing returned - but the memory subsystem is enabled
104  *******************************************************************************
105  */
106
107 #include <config.h>
108
109 .section .text
110 .equ            DRCCTL,     0x0fffef010   /* DRAM control register */
111 .equ            DRCTMCTL,   0x0fffef012   /* DRAM timing control register */
112 .equ            DRCCFG,     0x0fffef014   /* DRAM bank configuration register */
113 .equ            DRCBENDADR, 0x0fffef018   /* DRAM bank ending address register */
114 .equ            ECCCTL,     0x0fffef020   /* DRAM ECC control register */
115 .equ            ECCINT,     0x0fffefd18   /* DRAM ECC nmi-INT mapping */
116 .equ            DBCTL,      0x0fffef040   /* DRAM buffer control register */
117
118 .equ            CACHELINESZ, 0x00000010   /* size of our cache line (read buffer) */
119 .equ            COL11_ADR,  0x0e001e00    /* 11 col addrs */
120 .equ            COL10_ADR,  0x0e000e00    /* 10 col addrs */
121 .equ            COL09_ADR,  0x0e000600    /*  9 col addrs */
122 .equ            COL08_ADR,  0x0e000200    /*  8 col addrs */
123 .equ            ROW14_ADR,  0x0f000000    /* 14 row addrs */
124 .equ            ROW13_ADR,  0x07000000    /* 13 row addrs */
125 .equ            ROW12_ADR,  0x03000000    /* 12 row addrs */
126 .equ            ROW11_ADR,  0x01000000    /* 11 row addrs/also bank switch */
127 .equ            ROW10_ADR,  0x00000000    /* 10 row addrs/also bank switch */
128 .equ            COL11_DATA, 0x0b0b0b0b    /* 11 col addrs */
129 .equ            COL10_DATA, 0x0a0a0a0a    /* 10 col data */
130 .equ            COL09_DATA, 0x09090909    /*  9 col data */
131 .equ            COL08_DATA, 0x08080808    /*  8 col data */
132 .equ            ROW14_DATA, 0x3f3f3f3f    /* 14 row data (MASK) */
133 .equ            ROW13_DATA, 0x1f1f1f1f    /* 13 row data (MASK) */
134 .equ            ROW12_DATA, 0x0f0f0f0f    /* 12 row data (MASK) */
135 .equ            ROW11_DATA, 0x07070707    /* 11 row data/also bank switch (MASK) */
136 .equ            ROW10_DATA, 0xaaaaaaaa    /* 10 row data/also bank switch (MASK) */
137
138
139  /*
140   * initialize dram controller registers
141   */
142 .globl mem_init
143 mem_init:
144         xorw    %ax,%ax
145         movl    $DBCTL, %edi
146         movb     %al, (%edi)             /* disable write buffer */
147
148         movl    $ECCCTL, %edi
149         movb     %al, (%edi)             /* disable ECC */
150
151         movl    $DRCTMCTL, %edi
152         movb    $0x1E,%al                /* Set SDRAM timing for slowest */
153         movb     %al, (%edi)
154
155  /*
156   * setup loop to do 4 external banks starting with bank 3
157   */
158         movl    $0xff000000,%eax         /* enable last bank and setup */
159         movl    $DRCBENDADR, %edi        /* ending address register */
160         movl     %eax, (%edi)
161
162         movl    $DRCCFG, %edi            /* setup */
163         movw    $0xbbbb,%ax              /* dram config register for  */
164         movw    %ax, (%edi)
165
166  /*
167   * issue a NOP to all DRAMs
168   */
169         movl    $DRCCTL, %edi            /* setup DRAM control register with */
170         movb    $0x1,%al                 /* Disable refresh,disable write buffer */
171         movb     %al, (%edi)
172         movl    $CACHELINESZ, %esi       /* just a dummy address to write for */
173         movw     %ax, (%esi)
174  /*
175   * delay for 100 usec? 200?
176   * ******this is a cludge for now *************
177   */
178         movw    $100,%cx
179 sizdelay:
180         loop    sizdelay                 /* we need 100 usec here */
181  /***********************************************/
182
183  /*
184   * issue all banks precharge
185   */
186         movb    $0x2,%al                 /* All banks precharge */
187         movb     %al, (%edi)
188         movw     %ax, (%esi)
189
190  /*
191   * issue 2 auto refreshes to all banks
192   */
193         movb    $0x4,%al                 /* Auto refresh cmd */
194         movb     %al, (%edi)
195         movw    $2,%cx
196 refresh1:
197         movw     %ax, (%esi)
198         loop    refresh1
199
200  /*
201   * issue LOAD MODE REGISTER command
202   */
203         movb    $0x3,%al                 /* Load mode register cmd */
204         movb     %al, (%edi)
205         movw     %ax, (%esi)
206
207  /*
208   * issue 8 more auto refreshes to all banks
209   */
210         movb    $0x4,%al                 /* Auto refresh cmd */
211         movb     %al, (%edi)
212         movw    $8,%cx
213 refresh2:
214         movw     %ax, (%esi)
215         loop    refresh2
216
217  /*
218   * set control register to NORMAL mode
219   */
220         movb    $0x0,%al                 /* Normal mode value */
221         movb     %al, (%edi)
222
223  /*
224   * size dram starting with external bank 3 moving to external bank 0
225   */
226         movl    $0x3,%ecx                /* start with external bank 3 */
227
228 nextbank:
229
230  /*
231   * write col 11 wrap adr
232   */
233         movl    $COL11_ADR, %esi         /* set address to max col (11) wrap addr */
234         movl    $COL11_DATA, %eax        /* pattern for max supported columns(11) */
235         movl    %eax, (%esi)             /* write max col pattern at max col adr */
236         movl    (%esi), %ebx             /* optional read */
237         cmpl    %ebx,%eax                /* to verify write */
238         jnz     bad_ram                  /* this ram is bad */
239  /*
240   * write col 10 wrap adr
241   */
242
243         movl    $COL10_ADR, %esi         /* set address to 10 col wrap address */
244         movl    $COL10_DATA, %eax        /* pattern for 10 col wrap */
245         movl    %eax, (%esi)             /* write 10 col pattern @ 10 col wrap adr */
246         movl    (%esi), %ebx             /* optional read */
247         cmpl    %ebx,%eax                /* to verify write */
248         jnz     bad_ram                  /* this ram is bad */
249  /*
250   * write col 9 wrap adr
251   */
252         movl    $COL09_ADR, %esi         /* set address to 9 col wrap address */
253         movl    $COL09_DATA, %eax        /* pattern for 9 col wrap */
254         movl    %eax, (%esi)             /* write 9 col pattern @ 9 col wrap adr */
255         movl    (%esi), %ebx             /* optional read */
256         cmpl    %ebx,%eax                /* to verify write */
257         jnz     bad_ram                  /* this ram is bad */
258  /*
259   * write col 8 wrap adr
260   */
261         movl    $COL08_ADR, %esi         /* set address to min(8) col wrap address */
262         movl    $COL08_DATA, %eax        /* pattern for min (8) col wrap */
263         movl    %eax, (%esi)             /* write min col pattern @ min col adr */
264         movl    (%esi), %ebx             /* optional read */
265         cmpl    %ebx,%eax                /* to verify write */
266         jnz     bad_ram                  /* this ram is bad */
267  /*
268   * write row 14 wrap adr
269   */
270         movl    $ROW14_ADR, %esi         /* set address to max row (14) wrap addr */
271         movl    $ROW14_DATA, %eax        /* pattern for max supported rows(14) */
272         movl    %eax, (%esi)             /* write max row pattern at max row adr */
273         movl    (%esi), %ebx             /* optional read */
274         cmpl    %ebx,%eax                /* to verify write */
275         jnz     bad_ram                  /* this ram is bad */
276  /*
277   * write row 13 wrap adr
278   */
279         movl    $ROW13_ADR, %esi         /* set address to 13 row wrap address */
280         movl    $ROW13_DATA, %eax        /* pattern for 13 row wrap */
281         movl    %eax, (%esi)             /* write 13 row pattern @ 13 row wrap adr */
282         movl    (%esi), %ebx             /* optional read */
283         cmpl    %ebx,%eax                /* to verify write */
284         jnz     bad_ram                  /* this ram is bad */
285  /*
286   * write row 12 wrap adr
287   */
288         movl    $ROW12_ADR, %esi         /* set address to 12 row wrap address */
289         movl    $ROW12_DATA, %eax        /* pattern for 12 row wrap */
290         movl    %eax, (%esi)             /* write 12 row pattern @ 12 row wrap adr */
291         movl    (%esi), %ebx             /* optional read */
292         cmpl    %ebx,%eax                /* to verify write */
293         jnz     bad_ram                  /* this ram is bad */
294  /*
295   * write row 11 wrap adr
296   */
297         movl    $ROW11_ADR, %edi         /* set address to 11 row wrap address */
298         movl    $ROW11_DATA, %eax        /* pattern for 11 row wrap */
299         movl    %eax, (%edi)             /* write 11 row pattern @ 11 row wrap adr */
300         movl    (%edi), %ebx             /* optional read */
301         cmpl    %ebx,%eax                /* to verify write */
302         jnz     bad_ram                  /* this ram is bad */
303  /*
304   * write row 10 wrap adr --- this write is really to determine number of banks
305   */
306         movl    $ROW10_ADR, %edi         /* set address to 10 row wrap address */
307         movl    $ROW10_DATA, %eax        /* pattern for 10 row wrap (AA) */
308         movl    %eax, (%edi)             /* write 10 row pattern @ 10 row wrap adr */
309         movl    (%edi), %ebx             /* optional read */
310         cmpl    %ebx,%eax                /* to verify write */
311         jnz     bad_ram                  /* this ram is bad */
312  /*
313   * read data @ row 12 wrap adr to determine  * banks,
314   * and read data @ row 14 wrap adr to determine  * rows.
315   * if data @ row 12 wrap adr is not AA, 11 or 12 we have bad RAM.
316   * if data @ row 12 wrap == AA, we only have 2 banks, NOT 4
317   * if data @ row 12 wrap == 11 or 12, we have 4 banks,
318   */
319         xorw    %di,%di                  /* value for 2 banks in DI */
320         movl    (%esi), %ebx             /* read from 12 row wrap to check banks
321                                           * (esi is setup from the write to row 12 wrap) */
322         cmpl    %ebx,%eax                /* check for AA pattern  (eax holds the aa pattern) */
323         jz      only2                    /* if pattern == AA, we only have 2 banks */
324
325         /* 4 banks */
326
327         movw    $8,%di                   /* value for 4 banks in DI (BNK_CNT bit) */
328         cmpl    $ROW11_DATA, %ebx        /* only other legitimate values are 11 */
329         jz      only2
330         cmpl    $ROW12_DATA, %ebx        /* and 12 */
331         jnz     bad_ram                  /* its bad if not 11 or 12! */
332
333         /* fall through */
334 only2:
335  /*
336   * validate row mask
337   */
338         movl    $ROW14_ADR, %esi         /* set address back to max row wrap addr */
339         movl    (%esi), %eax             /* read actual number of rows @ row14 adr */
340
341         cmpl    $ROW11_DATA, %eax        /* row must be greater than 11 pattern */
342         jb      bad_ram
343
344         cmpl    $ROW14_DATA, %eax        /* and row must be less than 14 pattern */
345         ja      bad_ram
346
347         cmpb    %ah,%al                  /* verify all 4 bytes of dword same */
348         jnz     bad_ram
349         movl    %eax,%ebx
350         shrl    $16,%ebx
351         cmpw    %bx,%ax
352         jnz     bad_ram
353  /*
354   * read col 11 wrap adr for real column data value
355   */
356         movl    $COL11_ADR, %esi         /* set address to max col (11) wrap addr */
357         movl    (%esi), %eax             /* read real col number at max col adr */
358  /*
359   * validate column data
360   */
361         cmpl    $COL08_DATA, %eax        /* col must be greater than 8 pattern */
362         jb      bad_ram
363
364         cmpl    $COL11_DATA, %eax        /* and row must be less than 11 pattern */
365         ja      bad_ram
366
367         subl    $COL08_DATA, %eax        /* normalize column data to zero */
368         jc      bad_ram
369         cmpb    %ah,%al                  /* verify all 4 bytes of dword equal */
370         jnz     bad_ram
371         movl    %eax,%edx
372         shrl    $16,%edx
373         cmpw    %dx,%ax
374         jnz     bad_ram
375  /*
376   * merge bank and col data together
377   */
378         addw    %di,%dx                  /* merge of bank and col info in dl */
379  /*
380   * fix ending addr mask based upon col info
381   */
382         movb    $3,%al
383         subb    %dh,%al                  /* dh contains the overflow from the bank/col merge  */
384         movb    %bl,%dh                  /* bl contains the row mask (aa, 07, 0f, 1f or 3f) */
385         xchgw   %cx,%ax                  /* cx = ax = 3 or 2 depending on 2 or 4 bank device */
386         shrb    %cl,%dh                  /*  */
387         incb    %dh                      /* ending addr is 1 greater than real end */
388         xchgw   %cx,%ax                  /* cx is bank number again */
389  /*
390   * issue all banks precharge
391   */
392 bad_reint:
393         movl    $DRCCTL, %esi            /* setup DRAM control register with */
394         movb    $0x2,%al                 /* All banks precharge */
395         movb     %al, (%esi)
396         movl    $CACHELINESZ, %esi       /* address to init read buffer */
397         movw     %ax, (%esi)
398
399  /*
400   * update ENDING ADDRESS REGISTER
401   */
402         movl    $DRCBENDADR, %edi        /* DRAM ending address register */
403         movl    %ecx,%ebx
404         addl    %ebx, %edi
405         movb    %dh, (%edi)
406  /*
407   * update CONFIG REGISTER
408   */
409         xorb    %dh,%dh
410         movw    $0x00f,%bx
411         movw    %cx,%ax
412         shlw    $2,%ax
413         xchgw   %cx,%ax
414         shlw    %cl,%dx
415         shlw    %cl,%bx
416         notw    %bx
417         xchgw   %cx,%ax
418         movl    $DRCCFG, %edi
419         mov     (%edi), %ax
420         andw    %bx,%ax
421         orw     %dx,%ax
422         movw    %ax, (%edi)
423         jcxz    cleanup
424
425         decw    %cx
426         movl    %ecx,%ebx
427         movl    $DRCBENDADR, %edi        /* DRAM ending address register */
428         movb    $0xff,%al
429         addl    %ebx, %edi
430         movb    %al, (%edi)
431  /*
432   * set control register to NORMAL mode
433   */
434         movl    $DRCCTL, %esi            /* setup DRAM control register with */
435         movb    $0x0,%al                 /* Normal mode value */
436         movb    %al, (%esi)
437         movl    $CACHELINESZ, %esi       /* address to init read buffer */
438         movw    %ax, (%esi)
439         jmp     nextbank
440
441 cleanup:
442         movl    $DRCBENDADR, %edi        /* DRAM ending address register  */
443         movw    $4,%cx
444         xorw    %ax,%ax
445 cleanuplp:
446         movb   (%edi), %al
447         orb     %al,%al
448         jz      emptybank
449
450         addb    %ah,%al
451         jns     nottoomuch
452
453         movb    $0x7f,%al
454 nottoomuch:
455         movb    %al,%ah
456         orb     $0x80,%al
457         movb    %al, (%edi)
458 emptybank:
459         incl    %edi
460         loop    cleanuplp
461
462 #if defined CONFIG_SYS_SDRAM_DRCTMCTL
463         /* just have your hardware desinger _GIVE_ you what you need here! */
464         movl    $DRCTMCTL, %edi
465         movb    $CONFIG_SYS_SDRAM_DRCTMCTL,%al
466         movb    (%edi), %al
467 #else
468 #if defined(CONFIG_SYS_SDRAM_CAS_LATENCY_2T) || defined(CONFIG_SYS_SDRAM_CAS_LATENCY_3T)
469         /* set the CAS latency now since it is hard to do
470          * when we run from the RAM */
471         movl    $DRCTMCTL, %edi          /* DRAM timing register */
472         movb    (%edi), %al
473 #ifdef CONFIG_SYS_SDRAM_CAS_LATENCY_2T
474         andb    $0xef, %al
475 #endif
476 #ifdef CONFIG_SYS_SDRAM_CAS_LATENCY_3T
477         orb     $0x10, %al
478 #endif
479         movb    %al, (%edi)
480 #endif
481 #endif
482         movl    $DRCCTL, %edi            /* DRAM Control register */
483         movb    $0x3,%al                 /* Load mode register cmd */
484         movb     %al, (%edi)
485         movw     %ax, (%esi)
486
487
488         movl    $DRCCTL, %edi            /* DRAM Control register */
489         movb    $0x18,%al                /*  Enable refresh and NORMAL mode */
490         movb    %al, (%edi)
491
492         jmp     dram_done
493
494 bad_ram:
495         xorl    %edx,%edx
496         xorl    %edi,%edi
497         jmp     bad_reint
498
499 dram_done:
500
501         /* readback DRCBENDADR and return the number
502          * of available ram bytes in %eax */
503
504         movl    $DRCBENDADR, %edi        /* DRAM ending address register  */
505
506         movl    (%edi), %eax
507         movl    %eax, %ecx
508         andl    $0x80000000, %ecx
509         jz      bank2
510         andl    $0x7f000000, %eax
511         shrl    $2, %eax
512         movl    %eax, %ebx
513
514 bank2:  movl    (%edi), %eax
515         movl    %eax, %ecx
516         andl    $0x00800000, %ecx
517         jz      bank1
518         andl    $0x007f0000, %eax
519         shll    $6, %eax
520         movl    %eax, %ebx
521
522 bank1:  movl    (%edi), %eax
523         movl    %eax, %ecx
524         andl    $0x00008000, %ecx
525         jz      bank0
526         andl    $0x00007f00, %eax
527         shll    $14, %eax
528         movl    %eax, %ebx
529
530 bank0:  movl    (%edi), %eax
531         movl    %eax, %ecx
532         andl    $0x00000080, %ecx
533         jz      done
534         andl    $0x0000007f, %eax
535         shll    $22, %eax
536         movl    %eax, %ebx
537
538
539 done:
540         movl    %ebx, %eax
541
542 #if CONFIG_SYS_SDRAM_ECC_ENABLE
543         /* A nominal memory test: just a byte at each address line */
544         movl    %eax, %ecx
545         shrl    $0x1, %ecx
546         movl    $0x1, %edi
547 memtest0:
548         movb    $0xa5, (%edi)
549         cmpb    $0xa5, (%edi)
550         jne     out
551         shrl    $1, %ecx
552         andl    %ecx,%ecx
553         jz      set_ecc
554         shll    $1, %edi
555         jmp     memtest0
556
557 set_ecc:
558         /* clear all ram with a memset */
559         movl    %eax, %ecx
560         xorl    %esi, %esi
561         xorl    %edi, %edi
562         xorl    %eax, %eax
563         shrl    $2, %ecx
564         cld
565         rep     stosl
566                         /* enable read, write buffers */
567         movb    $0x11, %al
568         movl    $DBCTL, %edi
569         movb    %al, (%edi)
570                         /* enable NMI mapping for ECC */
571         movl    $ECCINT, %edi
572         mov     $0x10, %al
573         movb    %al, (%edi)
574                         /* Turn on ECC */
575         movl    $ECCCTL, %edi
576         mov     $0x05, %al
577         movb    %al, (%edi)
578 #endif
579 out:
580         movl    %ebx, %eax
581         jmp     *%ebp