> -----Original Message-----
> From: David Woodhouse [mailto:[EMAIL PROTECTED]] 
> Sent: Tuesday, April 24, 2001 2:33 PM
> To: [EMAIL PROTECTED]
> Cc: Vipin Malik; Alex Lennon; [EMAIL PROTECTED]; jffs-dev;
> [EMAIL PROTECTED]
> Subject: Re: Elan SC520 - problem with MTD 
> 
> 
> 
> 
> 
> [EMAIL PROTECTED] said:
> >  I have some code that does the basic SC520 initialization 
> right after
> > reset and I am now trying to initialize the Super I/O chip (I have
> > just received the chip manual from Acerlabs). After that, I need to
> > figure out a way to setup the set up the PCI bridge... Another thing
> > that is still missing in my code is a proper RAM size detection.
> 
> > So any working code you might have along these lines -no matter how
> > ugly- would probably be helpful to me.


   I have a system with the Elan520 evaluation board working completely from flash.
Here is some of the code used. It is based on AMD codekits, check their website
to verify latest news.
//==============================================================================
// FILE   :  ram_sizer.S
// =============================================================================
//
// It will then intialize the SDRAM
//
// ============================================================================

#include "asm.hs"
#include "elan520sc.hs"

.code32
.text

//============================================================================
//                Automatic RAM configuration
//============================================================================
.code32
.globl  sizemem
.align  4
sizemem:

        xorw    %ax,          %ax
        movl    $DBCTL,       %edi                 //
        movb    %al,          (%edi)       // disable write buffer/read-ahead buffer
        movl    $ECCCTL,      %edi                 //
        movb    %al,          (%edi)       // disable ECC

        movl    $DRCTMCTL,    %edi                 //
        movb    $0x1E,        %al                  // Set SDRAM timing for slowest
        movb    %al,          (%edi)       // speed.

    //
    // setup loop to do 4 external banks starting with bank 3
    //
        movl    $0x0ff000000, %eax               // enable last bank and setup
        movl    $DRCBENDADR,  %edi               // ending address register
        movl    %eax,         (%edi)     // for max ram in last bank

        movl    $DRCCFG,      %edi               // setup
        movw    $0x0bbbb,     %ax                // dram config register for
        movw    %ax,          (%edi)     // all banks with max cols and max banks

    //
    // issue a NOP to all DRAMs
    //
        movl    $DRCCTL,      %edi               // setup DRAM control register with
        movb    $0x01,        %al                // Disable refresh,disable write 
buffer
        movb    %al,          (%edi)     // Test Mode and NOP command select
        movl    $CACHELINESZ, %esi               // just a dummy address to write for
        movw    %ax,          (%esi)     // NOP cmd to take effect
    //
    // delay for 100 usec? 200?
    //------------ this is a cludge for now ----------
        movw    $100,  %cx
sizdelay:
        loop    sizdelay        // we need 100 usec here
    //------------------------------------------------

    //
    // issue all banks precharge
    //
        movb    $0x02,    %al               // All banks precharge
        movb    %al,      (%edi)            //
        movw    %ax,      (%esi)            // write needed for cmd to take effect

    //
    // issue 2 auto refreshes to all banks
    //
        movb    $0x04,    %al               // Auto refresh cmd
        movb    %al,      (%edi)            //
        movw    $2,       %cx
refresh1:
        movw    %ax,      (%esi)            // write needed for cmd to take effect
        loop    refresh1

    //
    // issue LOAD MODE REGISTER command
    //
        movb    $0x03,    %al               // Load mode register cmd
        movb    %al,      (%edi)            //
        movw    %ax,      (%esi)            // write needed for cmd to take effect

    //
    // issue 8 more auto refreshes to all banks
    //
        movb    $0x04,    %al               // Auto refresh cmd
        movb    %al,      (%edi)            //
        movw    $8,       %cx
refresh2:
        movw    %ax,      (%esi)            // write needed for cmd to take effect
        loop    refresh2

    //
    // set control register to NORMAL mode
    //
        movb    $0x00,    %al               // Normal mode value
        movb    %al,      (%edi)            //

    //
    // size dram starting with external bank 3 moving to external bank 0
    //
        movl    $0x3,     %ecx              // start with external bank 3

nextbank:

    //
    // write col 11 wrap adr
    //
        movl    $COL11_ADR,   %esi             // set address to max col (11) wrap addr
        movl    $COL11_DATA,  %eax             // pattern for max supported columns(11)
        movl    %eax,         (%esi)   // write max col pattern at max col adr
        movl    (%esi),   %ebx         // optional read
        cmpl    %ebx,         %eax             // to verify write
        jnz        bad_ram                         // this ram is bad
    //
    // write col 10 wrap adr
    //
        movl    $COL10_ADR,   %esi             // set address to 10 col wrap address
        movl    $COL10_DATA,  %eax             // pattern for 10 col wrap
        movl    %eax,         (%esi)   // write 10 col pattern @ 10 col wrap adr
        movl    (%esi),   %ebx         // optional read
        cmpl    %ebx,         %eax             // to verify write
        jnz        bad_ram                         // this ram is bad
    //
    // write col 9 wrap adr
    //
        movl    $COL09_ADR,   %esi             // set address to 9 col wrap address
        movl    $COL09_DATA,  %eax             // pattern for 9 col wrap
        movl    %eax,         (%esi)   // write 9 col pattern @ 9 col wrap adr
        movl    (%esi),   %ebx         // optional read
        cmpl    %ebx,         %eax         // to verify write
        jnz        bad_ram                         // this ram is bad
    //
    // write col 8 wrap adr
    //
        movl    $COL08_ADR,   %esi             // set address to min(8) col wrap 
address
        movl    $COL08_DATA,  %eax             // pattern for min (8) col wrap
        movl    %eax,         (%esi)   // write min col pattern @ min col adr
        movl    (%esi),   %ebx         // optional read
        cmpl    %ebx,         %eax             // to verify write
        jnz        bad_ram                         // this ram is bad
    //
    // write row 14 wrap adr
    //
        movl    $ROW14_ADR,   %esi              // set address to max row (14) wrap 
addr
        movl    $ROW14_DATA,  %eax              // pattern for max supported rows(14)
        movl    %eax,         (%esi)    // write max row pattern at max row adr
        movl    (%esi),   %ebx          // optional read
        cmpl    %ebx,         %eax              // to verify write
        jnz         bad_ram                         // this ram is bad
    //
    // write row 13 wrap adr
    //
        movl    $ROW13_ADR,   %esi              // set address to 13 row wrap address
        movl    $ROW13_DATA,  %eax              // pattern for 13 row wrap
        movl    %eax,         (%esi)    // write 13 row pattern @ 13 row wrap adr
        movl    (%esi),   %ebx          // optional read
        cmpl    %ebx,%eax                       // to verify write
        jnz        bad_ram                          // this ram is bad
    //
    // write row 12 wrap adr
    //
        movl    $ROW12_ADR,   %esi             // set address to 12 row wrap address
        movl    $ROW12_DATA,  %eax             // pattern for 12 row wrap
        movl    %eax,         (%esi)   // write 12 row pattern @ 12 row wrap adr
        movl    (%esi),   %ebx         // optional read
        cmpl    %ebx,         %eax             // to verify write
        jnz         bad_ram                        // this ram is bad
    //
    // write row 11 wrap adr
    //
        movl    $ROW11_ADR,   %edi             // set address to 11 row wrap address
        movl    $ROW11_DATA,  %eax             // pattern for 11 row wrap
        movl    %eax,         (%edi)   // write 11 row pattern @ 11 row wrap adr
        movl    (%edi),   %ebx         // optional read
        cmpl    %ebx,         %eax             // to verify write
        jnz        bad_ram                         // this ram is bad
    //
    // write row 10 wrap adr --- this write is really to determine number of banks
    //
        movl    $ROW10_ADR,   %edi             // set address to 10 row wrap address
        movl    $ROW10_DATA,  %eax             // pattern for 10 row wrap (AA)
        movl    %eax,         (%edi)   // write 10 row pattern @ 10 row wrap adr
        movl    (%edi),   %ebx         // optional read
        cmpl    %ebx,         %eax             // to verify write
        jnz        bad_ram                         // this ram is bad
    //
    // 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,
    //
        xorw    %di,          %di              // value for 2 banks in DI
        movl    (%esi),   %ebx         // read from 12 row wrap to check banks
        cmpl    %ebx,         %eax             // check for AA pattern
        movl    $ROW14_ADR,   %esi             // set address back to max row wrap addr
        movl    (%esi),   %eax         // read actual number of rows @ row14 adr
        jz        only2                        // if pattern == AA, we only have 2 
banks

        movw    $0x0008,      %di              // value for 4 banks in DI
        cmpl    $ROW11_DATA,  %ebx             // only other legitimate values are 11
        jz          only2
        cmpl    $ROW12_DATA,  %ebx             // and 12
        jnz         bad_ram                        // its bad if not 11 or 12!

only2:
    //
    // validate row mask
    //
        cmpl    $ROW11_DATA,  %eax             // row must be greater than 11 pattern
        jb          bad_ram

        cmpl    $ROW14_DATA,  %eax             // and row must be less than 14 pattern
        ja          bad_ram

        cmpb    %ah,          %al              // verify all 4 bytes of dword same
        jnz         bad_ram
        movl    %eax,         %ebx
        shrl    $16,          %ebx
        cmpw    %bx,          %ax
        jnz         bad_ram
    //
    // read col 11 wrap adr for real column data value
    //
        movl    $COL11_ADR,   %esi         // set address to max col (11) wrap addr
        movl    (%esi),   %eax     // read real col number at max col adr
    //
    // validate column data
    //
        cmpl    $COL08_DATA, %eax           // col must be greater than 8 pattern
        jb          bad_ram

        cmpl    $COL11_DATA, %eax           // and row must be less than 11 pattern
        ja          bad_ram

        subl    $COL08_DATA,  %eax          // normalize column data to zero
        jc          bad_ram
        cmpb    %ah,          %al           // verify all 4 bytes of dword equal
        jnz         bad_ram
        movl    %eax,         %edx
        shr         $16,          %edx
        cmpw    %dx,          %ax
        jnz         bad_ram
    //
    // merge bank and col data together
    //
        addw    %di,%dx                // merge of bank and col info in dl
    //
    // fix ending addr mask based upon col info
    //
        movb    $3,           %al
        subb    %dh,          %al
        movb    %bl,          %dh
        xchgw   %cx,          %ax
        shrb    %cl,          %dh
        incb    %dh                               // ending addr is 1 greater than 
real end
        xchgw   %cx,          %ax
    //
    // issue all banks precharge
    //
bad_reint:
        movl    $DRCCTL,      %esi                // setup DRAM control register with
        movb    $0x02,        %al                 // All banks precharge
        movb    %al,          (%esi)      //
        movl    $CACHELINESZ, %esi                // address to init read buffer
        movw    %ax,          (%esi)      // write needed for cmd to take effect

    //
    // update ENDING ADDRESS REGISTER
    //
        movl    $DRCBENDADR, %edi                     // DRAM ending address register
        movl    %ecx,        %ebx
        movb    %dh,         %fs:(%ebx, %edi)     // write ending address for this bank
    //
    // update CONFIG REGISTER
    //
        xorb    %dh,          %dh
        movw    $0x000f,      %bx
        movw    %cx,          %ax
        shlw    $2,           %ax
        xchgw   %cx,          %ax
        shlw    %cl,          %dx
        shlw    %cl,          %bx
        notw    %bx
        xchgw   %cx,          %ax
        movl    $DRCCFG,      %edi
        movw    (%edi),   %ax
        andw    %bx,          %ax
        orw         %dx,          %ax
        movw    %ax,          (%edi)
    //
    //
    //
        jcxz    cleanup

        decw    %cx
        movl    %ecx,         %ebx
        movl    $DRCBENDADR,  %edi                         // DRAM ending address 
register
        movb    $0x0ff,       %al
        movb    %al,          %fs:(%ebx, %edi)         // enable next bank for max 
ending addr
    //
    // set control register to NORMAL mode
    //
        movl    $DRCCTL,      %esi                         // setup DRAM control 
register with
        movb    $0x00,        %al                          // Normal mode value
        movb    %al,          (%esi)                   //
        movl    $CACHELINESZ, %esi                         // address to init read 
buffer
        movw    %ax,          (%esi)                   // write needed for cmd to take 
effect
        jmp        nextbank

    //
    //
cleanup:
        movl    $DRCBENDADR,  %edi                         // DRAM ending address 
register
        movw    $4,           %cx
        xorw    %ax,          %ax
cleanuplp:
        movb     (%edi),  %al
        orb          %al,         %al
        jz          emptybank

        addb    %ah,          %al
        jns         nottoomuch

        movb    $0x07f,       %al
nottoomuch:
        movb    %al,          %ah
        orb         $0x80,        %al
        movb    %al,          (%edi)
emptybank:
        incl    %edi
        loop    cleanuplp

        movl    $DRCCTL,      %edi                      // DRAM Control register
        movb    $0x18,        %al                       // Enable refresh and NORMAL 
mode
        movb    %al,          (%edi)                // and 15.6 usec refresh rate


    // get ram size from "DRC BankEndAddress"
    // ecx counter
    // esi pointer to BankEndAddress
    movl    $0x3,         %ecx
        movl    $DRCBENDADR,  %esi                      // DRAM ending address register
.Lcaltotalram:
        movl    (%esi),       %edx

        movl    %ecx,         %ebx                 // save counter
        shl     $3,           %ecx                 // multipy counter to get number of 
bits
        shr     %cl,          %edx                 // place into lower byte the 
bank_reg[counter]
    movl    %ebx,         %ecx                 // restore counter

        test    $128,         %edx                 // bank enabled ?
    jz      .LBankDisabled
    // theorically  edx by 4Meg == ramsize
    andl    $127,         %edx                 // get bank ending address
    movl    %edx,         %eax
    shl     $22,          %eax                 // multiply by 4Megs 0x400000
    jmp     .LTotalSizeDone
.LBankDisabled:
    loop    .Lcaltotalram
.LTotalSizeDone:                               // eax dram size in bytes

    //--- Ram Sizing FINISHES return with %ebp address
        jmp     *%ebp                               // return thanks to ebp

.align 4
bad_ram:
        xor        %edx,       %edx
        xorl   %edi,       %edi
        jmp        bad_reint

//========================================================================================


*********************************************************************************
from start32.S
*********************************************************************************
.equiv  gdt_table_size, 5 * SIZE_GDT_ENTRY         // gdt_table_end - gdt_table

.code32
.text
.global  _start_32
//----------------------------------------------------------------------
_start_32:

// now reload all of the segment registers with descriptor 0x18
    xorl    %eax,      %eax              // clear eax (porque movw ax, fs se traduce a 
movl ??)
        movw    $SEG32_DS, %ax              // set segment base to descriptor 0x018
        movw    %ax,       %fs
        movw    %ax,       %ds              // use DS
        movw    %ax,       %gs              // use GS
        movw    %ax,       %es              // use ES
        movw    %ax,       %ss              // use ES

    //---- output a 3 to led 680, segments changed
    movw        $0x0680,   %dx
        movw    $0x04,     %ax
        outw    %ax,       %dx
    DELAY_LOOP

//-----------------------------------------------------------------------
// all accesses to data from now on are now done in 32 bit
// mode.  As a result, we don't need the CBAR alias anymore.
// to prevent any possible problems with the alias interfering
// with any loaded code or data, we turn off the CBAR alias here.
//-----------------------------------------------------------------------
        movw    $CBAR,        %dx   // set the new MMCR base to 0df00:0h
        movl    $0x0CB,       %eax      // that is: cancel the alias
        outl    %eax,         %dx       // 32 bit register

//-----------------------------------------------------------------------
// Now that we have access to 32 bit memory space, we
// setup the SDRAM controller and initialize the SDRAM.
// perform dynamic DRAM sizing
//-----------------------------------------------------------------------
        movl    $dram_done, %ebp       // return address (we still don't have a stack)
        jmp         sizemem                // jump to the dram dynamic sizing routine
dram_done:
    movl    %eax,     %ebp         // !!!! now EBP contains TOTAL RAM SIZE in bytes

    //------------------- output a 4 to led 680, dram done
        movw    $0x0680,  %dx
        movw    $0x04,    %ax
        outw    %ax,      %dx
    //-----------------------------------------------------------

    // -------------------- Ram Parameters init  ------------------------ JB
        movl    $ECCCTL,  %edi        // ECC Control
        movl    $0x0,     %eax
        movb    %al,      (%edi)          // disable RAM ECC (in fact, it already was)

        movl    $DRCTMCTL,    %edi    // SDram Timing Control
        movb    (RamTimings), %al     // CAS Latency 3T, RAS Precharge Delay 3T, RAS 
to CAS delay 3T => 000 1  01  01
        movb    %al,          (%edi)

    //------------------- output a 5 to led 680, dram configured
        movw    $0x0680,  %dx
        movw    $0x05,    %ax
        outw    %ax,      %dx

    movb        (RamTestDisabled),      %al
    testb   %al,          %al
    jnz         test_stack


.equ    VAL_5A, 0x5A5A5A5A
.equ    VAL_A5, 0xA5A5A5A5
    //--------------- RAM test (cache disabled but memory at full-speed) --------
    cld
    //--- write 0x5A5A5A5A to RAM
    movl    $0x0,       %edi          // destination
    movl    %ebp,       %ecx
    shr     $2,         %ecx          // RAM doubleword size (div 4)
    movl    $VAL_5A,    %eax
    rep stosl

    //------------------- output a 6 to led 680, dram to 5A written
        movw    $0x0680,    %dx
        movw    $0x06,      %ax
        outw    %ax,        %dx

    //--- verify that RAM is 0x5A5A5A5A
    movl    $0x0,       %edi          // scan destination
    movl    %ebp,       %ecx
    shr     $2,         %ecx          // RAM doubleword size
    movl    $VAL_5A,    %eax
    repe scasl                        // repeat while equal
    jne     ram_test_err

    //------------------- output a 7 to led 680, dram 5A test done
        movw    $0x0680,    %dx
        movw    $0x07,      %ax
        outw    %ax,        %dx

    //--- write 0xA5A5A5A5 to RAM
    movl    $0x0,       %edi          // destination
    movl    %ebp,       %ecx
    shr     $2,         %ecx          // RAM doubleword size (div 4)
    movl    $VAL_A5,    %eax
    rep stosl

    //------------------- output a 8 to led 680, dram to A5 written
        movw    $0x0680,    %dx
        movw    $0x08,      %ax
        outw    %ax,        %dx

    //--- verify RAM to 0xA5A5A5A5
    movl    $0x0,       %edi          // scan destination
    movl    %ebp,       %ecx
    shr     $2,         %ecx          // RAM doubleword size
    movl    $VAL_A5,    %eax
    repe scasl                        // repeat while equal
    jne     ram_test_err

        //------- output a 9 to led 680, dram to A5 done
        movw    $0x0680,  %dx
        movw    $0x09,    %ax
        outw    %ax,      %dx

test_stack:
      ...
*********************************************************************************
      Juan Bertran
      UNIDESA
      Pi i Margall 201
      08224 - Terrassa
      SPAIN
      e-mail: [EMAIL PROTECTED]


Reply via email to